COUNT и ПРИСОЕДИНЯЙТЕСЬ с вычислениями в MYSQL - PullRequest
0 голосов
/ 04 ноября 2011

Попытка получить простой СЧЕТ из таблицы, которая занимает пару соединений и немного математики. Я не могу понять это правильно. Я продолжаю сталкиваться с «недопустимым использованием групповой функции». В аналогичном запросе я получаю все данные, просто не могу подсчитать.

У меня есть 4 таблицы.

CUSTOMERS
id  name  thegroup periodicity
1   Foo     3        4

GROUPS
id  group_name
3    New York

У каждого клиента есть ряд дат получения.

COLLECTIONS
id  coll_date   customer_id
3   2011-09-07  1
3   2011-07-21  1

И таблица периодов, в которой указывается количество недель между запланированными погрузками.

PERIODS
id  duration
4   4

Таким образом, длительность 4 означает получение каждые 4 недели или 28 дней.

Я могу рассчитать, когда приближается следующая дата получения: если у них периодичность 28 дней, то когда прошло 21 день с момента последнего получения, пришло время пометить его. В этом случае это будет 75% через его периодичность 21/28, или:

(ABS(DATEDIFF(MAX(collections.coll_date), NOW())) / (periods.duration *7))

Если этот результат больше 0,75, то он должен быть забран. Я могу просмотреть клиентов и рассчитать, что это не проблема.

Моя цель: Мне нужно знать, сколько клиентов в каждой группе должно быть забрано, повторно: COUNT (клиенты), ГДЕ (этот расчет)> .75 GROUP BY group.id.

Пока у меня есть это, но я не могу понять это правильно.

SELECT COUNT(*), groups.id
FROM customers
INNER JOIN groups ON customers.thegroup = groups.id
INNER JOIN periods ON customers.periodicity = periods.id
LEFT JOIN collections ON customers.id = collections.rest_id
WHERE  status = 1 AND (ABS(DATEDIFF(MAX(collections.coll_date), NOW()))/(periods.duration*7)) > .75
GROUP BY groups.id

Ответы [ 3 ]

0 голосов
/ 04 ноября 2011

MAX() - это агрегатная функция, которая не должна использоваться после предложения where, вы можете попробовать having вместо

0 голосов
/ 04 ноября 2011

Чтобы составить список всех групп, в которых хотя бы у одного клиента есть как минимум один срок получения, в соответствии с вашими расчетами, и в нем показано, сколько клиентов имеет срок получения, используйте следующую команду:

SELECT 
C.THEGROUP,
COUNT(DISTINCT C.ID) CNT
FROM CUSTOMERS C 
INNER JOIN PERIODS P ON C.PERIODICITY = P.ID
LEFT OUTER JOIN (SELECT CL.REST_ID CUSTID, MAX (CL.COLL_DATE) MCOLLD FROM COLLECTIONS CL GROUP BY CL.REST_ID) X ON C.ID = X.CUSTID
WHERE C.STATUS = 1 AND (ABS(DATEDIFF(X.MCOLLD, NOW()))/(P.DURATION*7)) > .75
GROUP BY C.THEGROUP

Если вы хотите, чтобы все группы в списке, включая группы, не имеющие пикапов, использовали

SELECT G.ID, IFNULL (A.CNT, 0) CNT FROM
GROUPS G
LEFT OUTER JOIN
(
SELECT 
C.THEGROUP,
COUNT(DISTINCT C.ID) CNT
FROM CUSTOMERS C 
INNER JOIN PERIODS P ON C.PERIODICITY = P.ID
LEFT OUTER JOIN (SELECT CL.REST_ID CUSTID, MAX (CL.COLL_DATE) MCOLLD FROM COLLECTIONS CL GROUP BY CL.REST_ID) X ON C.ID = X.CUSTID
WHERE C.STATUS = 1 AND (ABS(DATEDIFF(X.MCOLLD, NOW()))/(P.DURATION*7)) > .75
GROUP BY C.THEGROUP
) A ON G.ID = A.THEGROUP
ORDER BY G.ID
0 голосов
/ 04 ноября 2011

Вы не можете использовать periods.duration в своем запросе, потому что это не зависит от вашего выражения GROUP BY.

...