postgresql группа по

0

Это мой запрос в Postgresql:

SELECT 
    C.id, S.domen, B.name, C.source_id, ST.name 
FROM "calls" C 
    INNER JOIN "site" S ON S.id=C.site_id 
    INNER JOIN "sources" ON sources.id=C.source_id 
    INNER JOIN "brand" B ON B.id = S.id_brand
    INNER JOIN "source_types" ST ON ST.id = "sources".type_id 
WHERE 
    ("calltime" >= '2017-12-01') AND 
    ("calltime" <= '2017-12-03') AND 
    (S."id_brand"='6') 
ORDER BY "calltime" LIMIT 50

И я получаю этот результат:

Изображение 174551

Теперь я пытаюсь сгруппировать по имени (последний столбец) этот результат, чтобы получить результат следующим образом:

Контекстная реклама - 17
SEO-10
.... 

И для этого я использую этот запрос:

SELECT 
    ST.name, count(ST.name) 
FROM "calls" C 
    INNER JOIN "site" S ON S.id=C.site_id 
    INNER JOIN "sources" ON sources.id=C.source_id 
    INNER JOIN "brand" B ON B.id = S.id_brand
    INNER JOIN "source_types" ST ON ST.id = "sources".type_id 
WHERE 
    ("calltime" >= '2017-12-01') AND 
    ("calltime" <= '2017-12-03') AND 
    (S."id_brand"='6') 
GROUP BY ST.name 
ORDER BY count(ST.name) DESC LIMIT 50

Но я получаю неправильный результат:

Изображение 174551

Похоже, что он принимает значения из столбца source_id. Что я делаю неправильно?

  • 0
    Вместо этого попробуйте count(*)
  • 0
    @Phil, результат тот же
Теги:
group-by

3 ответа

1

Попробуйте это: если вы вызываете группу по лимиту, результат группируется по всем записям. Таким образом, сначала фильтруйте группу.

    SELECT 
        name, count(name) 
    FROM(
    SELECT 
        ST.name 
    FROM "calls" C 
        INNER JOIN "site" S ON S.id=C.site_id 
        INNER JOIN "sources" ON sources.id=C.source_id 
        INNER JOIN "brand" B ON B.id = S.id_brand
        INNER JOIN "source_types" ST ON ST.id = "sources".type_id 
    WHERE 
        ("calltime" >= '2017-12-01') AND 
        ("calltime" <= '2017-12-03') AND 
        (S."id_brand"='6') 
    ORDER BY "calltime" LIMIT 50
    ) T 
    GROUP BY name 
  • 0
    Спасибо, это работает!
0

Возможно, что 49 - это просто совпадение. Пытаться:

SELECT 
    ST.name, count(*) 
FROM "calls" C 
    INNER JOIN "site" S ON S.id=C.site_id 
    INNER JOIN "sources" ON sources.id=C.source_id 
    INNER JOIN "brand" B ON B.id = S.id_brand
    INNER JOIN "source_types" ST ON ST.id = "sources".type_id 
WHERE 
    ("calltime" >= '2017-12-01') AND 
    ("calltime" <= '2017-12-03') AND 
    (S."id_brand"='6') AND 
    C.source_id > 50
GROUP BY ST.name 
ORDER BY count(*) DESC LIMIT 50

Все, что я сделал, это изменить его на count(*) и добавить AND C.source_id > 50 в предложение Where. Посмотрим, изменит ли это счет.

Также вы можете просто запустить это:

SELECT 
    count(*) 
FROM "calls" C 
    INNER JOIN "site" S ON S.id=C.site_id 
    INNER JOIN "sources" ON sources.id=C.source_id 
    INNER JOIN "brand" B ON B.id = S.id_brand
    INNER JOIN "source_types" ST ON ST.id = "sources".type_id 
WHERE 
    ("calltime" >= '2017-12-01') AND 
    ("calltime" <= '2017-12-03') AND 
    (S."id_brand"='6') 

Это дает вам общее количество всех строк (я удалил GROUP BY). Если это число равно суммарному количеству сгруппированных строк, то они действительно являются подсчетами. Мы ищем 127 что составляет 49 + 30 + 21 + 13 + 9 + 4 + 1

Надеюсь, это поможет.

0

LIMIT 50 во втором запросе выполняется после GROUP BY.

Если вы хотите агрегировать только первые 50 строк, напишите LIMIT 50 в подзапрос и выполните GROUP BY во внешнем SELECT.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню