我有下表table
:
| id | id_a | id_b | date | day_part |
===============================================
32043 | 0 | 0 | 2015-12-03 | A |
31933 | 0 | 31933 | 2015-12-03 | A |
31908 | 0 | 0 | 2015-12-03 | A |
31384 | 0 | 31384 | 2015-11-30 | M |
31335 | 0 | 0 | 2015-11-30 | M |
31303 | 0 | 31303 | 2015-11-30 | M |
31302 | 0 | 0 | 2015-11-30 | M |
31300 | 0 | 0 | 2015-11-30 | M |
31223 | 0 | 0 | 2015-12-03 | A |
31221 | 0 | 31221 | 2015-11-30 | M |
32037 | 0 | 32037 | 2015-12-03 | A |
31301 | 31301| 0 | 2015-11-30 | M |
31901 | 31301| 0 | 2015-11-30 | M |
id
是唯一ID,day_part
是指当天的部分('A'表示'下午','M'表示'早上')。
假设我的日期范围介于2015-11-30
和2015-12-06
之间。
对于每一天,我需要找到每个COUNT
的{{1}}字段的id
:
day_part
我可以轻松地做到:
| date | M_ids_count | A_ids_count |
=========================================
2015-11-30 | 8 | 0
2015-12-03 | 0 | 5
现在棘手的部分是:
我需要返回以下结果:
SELECT
date,
SUM(CASE WHEN day_part = 'M' THEN 1 ELSE 0 END) AS M_ids_count,
SUM(CASE WHEN day_part = 'A' THEN 1 ELSE 0 END) AS A_ids_count
FROM table
WHERE date BETWEEN '2015-11-30' AND '2015-12-06'
AND day_part IN ("M", "A")
GROUP BY date;
我们现在已经开始计算| date | M_ids_count | A_ids_count | M_trips_count | A_trips_count |
=========================================================================
2015-11-30 | 8 | 0 | 7 | 0
2015-12-03 | 0 | 5 | 0 | 5
和M_ids_count
。
A_ids_count
与第n M_trips_count
和第n date
相关,并按以下方式计算:
条件1:如果我对同一day_part
和id_a
有相同的date
,我需要求和day_part
(即,我在这里);
条件2:如果我1
是id_a
并且我有相同的0
,我需要总结id_b
(当然,例如,如果我有1
= 0和三个不同的id_a
,我需要总结id_b
);
条件3:否则,如果3
和id_a
为id_b
,我需要对记录的0
求和;
COUNT
和A_trips_count
也是如此,但它与下午A_trips_count
的{{1}}有关。
因此,在我们的情况下,如果您查看date
,您会看到两个字段day_part
(table
31301 和 31901 < / strong>)具有相同的id_a = 31301
和id
。这将计算date
,因为它符合day_part
的要求。
然后,应将此1
添加到符合Condition 1
的同一1
和COUNT
Condition 2
的记录date
中:day_part
(3
s 31384,31303,31221)。这里我们总共有id
。
然后,应将此4
添加到符合4
的同一COUNT
和Condition 3
date
的记录day_part
中:3
(id
s - &gt; 31335,31302和31300)。
因此,我们得到7
M_trips_count
的值2015-11-30
和M
day_part
(即早晨)。同一A_trips_count
的{{1}}计算应相同,但与下午相关。
然后,date
和dates
之间的另一个2015-11-30
也是如此(在我们的例子中仅针对2015-12-06
date
不是其他日期)。与2015-12-03
相同的M_trips_count
和A_trips_count
计算。
现在,我可以/如何只使用一个SQL查询来完成它?
我需要的结果是(与上面相同):
2015-11-30
感谢您的关注!
答案 0 :(得分:1)
尝试以下代码大部分都可以使用。
SELECT t.dp AS date_part,
SUM(t.M_ids_count) AS M_ids_count,
SUM(t.A_ids_count) AS A_ids_count,
SUM(IF(t.M_trip_count = 'M_NULL', 0, (IF(t.M_trip_count = 'M_SAME', t.M_ids_count, 1)))) AS M_trip_count,
SUM(IF(t.A_trip_count = 'A_NULL', 0, (IF (t.A_trip_count = 'A_SAME', t.A_ids_count, 1)))) AS A_trip_count
FROM (
SELECT
date_part AS dp,
SUM(CASE WHEN day_part = 'M' THEN 1 ELSE 0 END) AS M_ids_count,
SUM(CASE WHEN day_part = 'A' THEN 1 ELSE 0 END) AS A_ids_count,
(CASE WHEN (day_part = 'M') THEN (IF(((id_a = 0 AND id_b = 0) OR (id_a = id_b)), 'M_SAME', 'M_DIFF')) ELSE 'M_NULL' END) AS M_trip_count,
(CASE WHEN (day_part = 'A') THEN (IF(((id_a = 0 AND id_b = 0) OR (id_a = id_b)), 'A_SAME', 'A_DIFF')) ELSE 'A_NULL' END) AS A_trip_count
FROM timer
WHERE date_part BETWEEN '2015-11-30' AND '2015-12-06' AND day_part IN ("M", "A")
GROUP BY id_a,id_b,M_trip_count,A_trip_count
) AS t
GROUP BY t.dp
这将按照您在上表中指定的表结构工作。
CREATE TABLE IF NOT EXISTS `timer` (
`id` int(11) NOT NULL,
`id_a` int(11) NOT NULL,
`id_b` int(11) NOT NULL,
`date_part` date NOT NULL,
`day_part` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `timer` (`id`, `id_a`, `id_b`, `date_part`, `day_part`) VALUES
(32043, 0, 0, '2015-12-03', 'A'),
(31933, 0, 31933, '2015-12-03', 'A'),
(31908, 0, 0, '2015-12-03', 'A'),
(31384, 0, 31384, '2015-11-30', 'M'),
(31335, 0, 0, '2015-11-30', 'M'),
(31303, 0, 31303, '2015-11-30', 'M'),
(31302, 0, 0, '2015-11-30', 'M'),
(31300, 0, 0, '2015-11-30', 'M'),
(31223, 0, 0, '2015-12-03', 'A'),
(31221, 0, 31221, '2015-11-30', 'M'),
(32037, 0, 32037, '2015-12-03', 'A'),
(31301, 31301, 0, '2015-11-30', 'M'),
(31901, 31301, 0, '2015-11-30', 'M');