Это мой запрос в 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
И я получаю этот результат:
Теперь я пытаюсь сгруппировать по имени (последний столбец) этот результат, чтобы получить результат следующим образом:
Контекстная реклама - 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
Но я получаю неправильный результат:
Похоже, что он принимает значения из столбца source_id
. Что я делаю неправильно?
Попробуйте это: если вы вызываете группу по лимиту, результат группируется по всем записям. Таким образом, сначала фильтруйте группу.
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
Возможно, что 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
Надеюсь, это поможет.
LIMIT 50
во втором запросе выполняется после GROUP BY
.
Если вы хотите агрегировать только первые 50 строк, напишите LIMIT 50
в подзапрос и выполните GROUP BY
во внешнем SELECT
.
count(*)