2012-02-26 4 views
-1

Имею некоторые проблемы с некоторыми SQL.Количество запросов SQL, деленное на разное количество того же запроса

Возьмем следующий результат, например:

LOC_CODE  CHANNEL    
------------ -------------------- 
3ATEST-01 CHAN2    
3ATEST-01 CHAN3    
3ATEST-02 CHAN4    

Что мне нужно сделать, это получить количество вышеуказанного запроса, сгруппированных по каналу, но я хочу, чтобы отсчет нужно разделить на число, что " LOC_CODE ".

Пример результата я после того, как есть:

CHANNEL   COUNT 
---------------- ---------- 
CHAN2   0.5 
CHAN3   0.5 
CHAN4   1 

Выше объяснений является то, что CHAN2 появляется рядом с «3ATEST-01», но LOC_CODE из «3ATEST-01» появляется дважды, поэтому счетчик следует разделить на 2.

Я знаю, что могу сделать это, в основном дублируя запрос с отдельным счетом, но базовый запрос довольно сложный и на самом деле не хочет нанести вред производительности.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация!

+1

Вопрос; КАНАЛ уникален? Если нет, можете ли вы привести пример результата, который вы хотите использовать с дублированным CHANNEL с другим LOC_CODE? –

+0

HI. Канал не уникален (первый результат может иметь канал в свое время). Я бы сделал сумму по окончательному внешнему запросу. – Lock

ответ

4

Try:

select channel, 
     count(*) over (partition by channel, loc_code) 
     /count(*) over (partition by loc_code) as count_ratio 
from my_table 
+0

Вы сэр - genuis – Lock

1
SELECT t.CHANNEL, COUNT(*)/gr.TotalCount 
FROM my_table t JOIN (
    SELECT LOC_CODE, COUNT(*) TotalCount 
    FROM my_table 
    GROUP BY LOC_CODE 
) gr USING(LOC_CODE) 
GROUP BY t.LOC_CODE, t.CHANNEL 

Создать индекс (LOC_CODE, CHANNEL)

Если нет повторяющихся каналов, замените COUNT(*)/gr.TotalCount с 1/gr.TotalCount и удалите пункт GROUP BY

+0

Есть ли другой способ, который не включает отдельный подзапрос для счета? Я не думаю, что есть, но мой запрос (my_table t в вашем примере выше) является довольно длинным запросом и хотел бы избежать дублирования этого только для счета. – Lock

+0

@ Lock: Я так не думаю. Одним из ваших требований является вывод результатов, сгруппированных по «Каналу». Другой - иметь вычисления из группы с помощью «Loc_Code». Если это возможно, возможно, это будет использовать аналитические (оконные) функции, как ответ Марка Баннистера. –

0

Ваши требования все еще немного неясно для меня, когда речь идет о дубликатах , но это должно работать, если вы хотите, чтобы группировка как на CHANNEL, так и на LOC_CODE подводила итоги позже;

SELECT L1.CHANNEL, 1/COUNT(L2.LOC_CODE) 
FROM Locations L1 
LEFT JOIN Locations L2 ON L1.LOC_CODE = L2.LOC_CODE 
GROUP BY L1.CHANNEL, L1.LOC_CODE 

Демо-версия here.

1

Во-первых, найти запрос, который получает вам правильные результаты. Затем посмотрите, можно ли его оптимизировать. Я предполагаю, что это трудно оптимизировать, так как вам нужны две разные группы, одна на Channel и одна до Loc_Code.

Я даже не уверен, что это соответствует вашему описанию:

SELECT t.CHANNEL 
    , COUNT(*)/SUM(grp.TotalCount) 
FROM my_table t 
    JOIN 
     (SELECT LOC_CODE 
      , COUNT(*) TotalCount  --- or is it perhaps?: 
              --- COUNT(DISTINCT CHANNEL) 
     FROM my_table 
     GROUP BY LOC_CODE 
    ) grp 
    ON grp.LOC_CODE = t.LOC_CODE 
GROUP BY t.CHANNEL 
Смежные вопросы