我最近将其发布在Stack Exchange的另一页中,但我认为这是更合适的选择。
好吧,标题似乎有些令人困惑,但我一直在努力提出我需要此查询的内容,以便最好地对其进行解释。我的数据库中有3个表(使用MySQL Workbench),但是对于此查询,我只是尝试使用一个表。名为service_data的表具有以下列:
Services_ID|Service_Type|Day|Time|Customer_ID(FK)
1001 |SERVICE1 |Mon|0950|1
1002 |SERVICE2 |Tue|1032|65
1003 |SERVICE3 |Wed|0859|4
该表包含大约200条记录,我的目标是将计时分组在一起,我通过这样做设法实现了这一目标:
select
case
WHEN (Delivery_Time between '08:00:00' and '09:00:00') then '0800-0900'
WHEN (Delivery_Time between '09:00:00' and '10:00:00') then '0900-1000'
WHEN (Delivery_Time between '10:00:00' and '11:00:00') then '1000-1100'
WHEN (Delivery_Time between '11:00:00' and '12:00:00') then '1100-1200'
WHEN (Delivery_Time between '12:00:00' and '13:00:00') then '1200-1300'
WHEN (Delivery_Time between '13:00:00' and '14:00:00') then '1300-1400'
WHEN (Delivery_Time between '14:00:00' and '15:00:00') then '1400-1500'
WHEN (Delivery_Time between '15:00:00' and '16:00:00') then '1500-1600'
WHEN (Delivery_Time between '16:00:00' and '17:00:00') then '1600-1700'
WHEN (Delivery_Time between '17:00:00' and '18:00:00') then '1700-1800'
WHEN (Delivery_Time between '18:00:00' and '19:00:00') then '1800-1900'
WHEN (Delivery_Time between '19:00:00' and '20:00:00') then '1900-2000'
WHEN (Delivery_Time between '20:00:00' and '21:00:00') then '2000-2100'
else 'Outside Opening Hours'
end as `Time Period`,
count(0) as 'count'
from service_data
group by `Time Period`
order by count desc
limit 20;
哪个会产生以下结果:
TimePeriod Count
1700-1800 24
1500-1600 21
1200-1300 19
1400-1500 19
1800-1900 17
1100-1200 17
1300-1400 16
1600-1700 16
1000-1100 16
1900-2000 12
0800-0900 12
0900-1000 11
我现在想做的是将计数进行拆分,以便有4个列分别标记为SERVICE1 SERVICE2 SERVICE3和SERVICE4(Service_Type列中的值。希望这样看起来像这样:
TimePeriod|SERVICE1|SERVICE2|SERVICE3|SERVICE4
1700-1800 | 6 | 7 | 10 | 1
1500-1600 | 5 | 9 | 1 | 6
1200-1300 | 0 | 4 | 2 | 13`
这可能!!我敢肯定它一定是,但是我一直在努力解决,SQL不是我的母语!任何帮助将不胜感激
我的第二个问题是:
我希望第二个查询能够完成上述所有操作,然后将结果链接到一个主键customer_id是service_data中的外键的customer_data表,并将customer_id链接到象限(customer_data表中的列值NE,SE,SW,NW取决于坐标),并再次按象限和服务对计数进行分组,因此如下所示:
TimePeriod| SERVICE1 | SERVICE2 | SERVICE3 | SERVICE4 |
-----------|NE|SE|SW|NW|NE|SE|SW|NW|NE|SE|SW|NW|NE|SE|SW|NW|
1700-1800 |2 |1 | 0| 3|4 | 0| 0|3 |2 |5 |2 |1 |0 |1 | 0| 0|
再次有可能吗?或者我要求太多了吗?我想知道是否可以通过某种方式使用SUM(IF)函数来实现所有这些功能?
答案 0 :(得分:0)
虽然我确实同意@Strawberry的观点,但是这确实需要一些入门知识。
这并没有针对性能或优雅进行任何优化,但如上所述,我已经使用您的数据对其进行了测试。
这是我的CREATE TABLE语句:
CREATE TABLE `service_data` (
`services_id` int(11) NOT NULL,
`service_type` varchar(45) DEFAULT NULL,
`day` varchar(45) DEFAULT NULL,
`time` time DEFAULT NULL,
`customer_id` int(11) DEFAULT NULL,
PRIMARY KEY (`services_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
首先获取您的时间范围。我已将准时时间缩短了一秒钟,以免造成每小时上班时间的浪费。
create view spans as
select time(concat(hour(time),':00:00')) as fromtime,
time(concat(hour(addtime(time,'00:59:59')),':00:00')) as totime
from service_data
现在查找每行数据的时间范围。
create view withspans as
select * from service_data s1
join spans s2
on time between fromtime and totime
现在汇总数据作为枢轴的输入。
create view summary as
select fromtime, totime, service_type, count(*) as spancount
from withspans
group by fromtime, totime, service_type
现在通过派生表进行数据透视。
select w.fromtime, w.totime,
s1.spancount as service1,
s2.spancount as service2,
s3.spancount as service3,
s4.spancount as service4
from summary w
left join (select * from summary where service_type = 'SERVICE1') s1
on s1.fromtime=w.fromtime and s1.totime=w.totime
left join (select * from summary where service_type = 'SERVICE2') s2
on s2.fromtime=w.fromtime and s2.totime=w.totime
left join (select * from summary where service_type = 'SERVICE3') s3
on s3.fromtime=w.fromtime and s3.totime=w.totime
left join (select * from summary where service_type = 'SERVICE4') s4
on s4.fromtime=w.fromtime and s4.totime=w.totime