|
Тема
|
GROUP BY date_column
|
|
Автор |
mr.vain (пътник 57) |
Публикувано | 24.08.06 14:44 |
|
Здравейте, имам следното питане по отношение на групирането по дата.
Имам (за примера) таблица с две полета: int & date.
Как да направя заявка, която да сумира int полето и да групира по дата , но при нулев резултат за дадена дата да ми връща 0 за тази дата, т.е.
SELECT SUM(int_field) AS mySum, date_field AS myDate
FROM myTable
WHERE date_field BETWEEN '2006-08-01' AND '2006-08-20'
GROUP BY date_field
ORDER BY date_field
mySum | myDate
5 | 2006-08-01
3 | 2006-08-04
1 | 2006-08-12
....
тази заявка е ОК, но при липсваща дата (липса на данни за дадена дата) няма да върне ред с дата и нулева стойност, т.е:
mySum | myDate
5 | 2006-08-01
0 | 2006-08-02
0 | 2006-08-03
3 | 2006-08-04
....
Благодаря за оказаната помощ. Става въпрос за MySQL.
Има три вида хора. Част от проблема, част от решението и част от пейзажа.Редактирано от mr.vain на 24.08.06 14:53.
| |
Тема
|
Re: GROUP BY date_column
[re: mr.vain]
|
|
Автор |
salle (един такъв) |
Публикувано | 24.08.06 15:36 |
|
Това си плаче за съхранена процедура:
CREATE TEMPORARY TABLE temp (d DATE);
INSERT INTO temp VALUES('2006-08-01'), ('2006-08-02'), ('2006-08-03'), ('2006-08-04'), ('2006-08-05'), ('2006-08-06'), ('2006-08-07'), ('2006-08-08'), ('2006-08-09'), ('2006-08-10'), ('2006-08-12'), ('2006-08-12'), ('2006-08-13'), ('2006-08-14'), ('2006-08-15'), ('2006-08-16'), ('2006-08-17'), ('2006-08-18'), ('2006-08-19'), ('2006-08-20');
SELECT temp.d AS myDate, IFNULL(t.mySum, 0) AS mySum
FROM temp LEFT JOIN
(SELECT SUM(int_field) AS mySum, date_field AS myDate
FROM myTable
WHERE date_field BETWEEN '2006-08-01' AND '2006-08-20'
GROUP BY date_field) AS t
ON(temp.d = t.myDate);
DROP TABLE temp;
Между другото MySQL сортира по подразбиране според GROUP BY клаузата
| |
Тема
|
Re: GROUP BY date_column
[re: salle]
|
|
Автор |
mr.vain (пътник 57) |
Публикувано | 24.08.06 16:11 |
|
Това е добре, благодаря за отговора! Но при положение, че периода е динамичен, с чести заявки към сървъра, подхода не е ли малко статичен и лош? Става въпрос за вадене на статистики. Иначе да, спокойно мога да налея една таблица с дати и да JOIN-вам.
Има ли вариант без процедура/друга таблица?
Има три вида хора. Част от проблема, част от решението и част от пейзажа.
| |
Тема
|
Re: GROUP BY date_column
[re: mr.vain]
|
|
Автор |
salle (един такъв) |
Публикувано | 24.08.06 18:07 |
|
"при положение, че периода е динамичен, с чести заявки към сървъра"
Именно
"налей" една статична таблица с дати, сложи и индекс по датата и действай.
Ето ти един "обълнат" вариант:
CREATE TEMPORARY TABLE temp (myDate DATE PRIMARY KEY, mySum BIGINT NOT NULL DEFAULT 0)
SELECT SUM(int_field) AS mySum, date_field AS myDate
FROM myTable
WHERE date_field BETWEEN '2006-08-01' AND '2006-08-20'
GROUP BY date_field
ORDER BY NULL;
INSERT IGNORE INTO temp (myDate) VALUES('2006-08-01'), ('2006-08-02'), ('2006-08-03'), ('2006-08-04'), ('2006-08-05'), ('2006-08-06'), ('2006-08-07'), ('2006-08-08'), ('2006-08-09'), ('2006-08-10'), ('2006-08-12'), ('2006-08-12'), ('2006-08-13'), ('2006-08-14'), ('2006-08-15'), ('2006-08-16'), ('2006-08-17'), ('2006-08-18'), ('2006-08-19'), ('2006-08-20');
SELECT * FROM temp ORDER BY myDate;;
DROP TABLE temp;
Честно казано аз бих го направил в клиентската част.
| |
Тема
|
Re: GROUP BY date_column
[re: mr.vain]
|
|
Автор |
wqw (АзСъмЖив) |
Публикувано | 26.08.06 18:51 |
|
За целта винаги е полезно да имаш една таблица Numbers с е дна колона с последователни числа от 0 до 10000 примерно. Ето нещо за MS-SQL:
DECLARE @FD DATETIME
, @TD DATETIME
SELECT @FD = '2006-08-01'
, @TD = '2006-08-20'
SELECT SUM(COALESCE(int_field, 0)) AS mySum
, @FD + myNumbers.SeqNo AS myDate
FROM myNumbers
LEFT JOIN myTable
ON myTable.date_field = @FD + myNumbers.SeqNo
WHERE myNumbers.SeqNo <= @TD-@FD
GROUP BY @FD + myNumbers.SeqNo
ORDER BY @FD + myNumbers.SeqNo
(not tested)
Ако искаш тествани работещи отовори, следващия път си направи труда да post-неш DDL на таблиците (CREATE TABLE ...) и малко sample input (INSERT ... SELECT ...)
cheers,
</wqw>
| |
|
|
|
|