如何按过去几周对数据进行分组?
How to group data by past few weeks?
我有一个原创的table是这样的,
timestamp_ID Country col1 col2 col3
2021-01-04 11:00:00 US red phone car
2021-01-04 11:00:00 US red sms car
2021-01-04 12:00:00 US red phone car
2021-01-07 11:00:00 UK red phone car
2021-01-08 11:00:00 US red phone airplane
2021-01-11 11:00:00 UK red sms car
2021-01-11 11:00:00 US green phone car
2021-01-12 11:00:00 US red phone car
2021-01-16 11:00:00 CA red sms car
2021-01-18 11:00:00 US blue phone airplane
2021-01-19 11:00:00 AU red phone car
2021-01-19 11:00:00 AU blue phone train
我可以在 SQL 中使用 GROUP BY 对我的数据进行分组以获得每周的汇总值吗?
我的预期输出是这样的,
Country col1 col2 col3 count_at_week1(2021-01-04~2021-01-10) count_at_week2 count_at_week3 ...
US red phone car 2 0 0
US red sms car 1 0 0
UK red phone car 1 0 0
US red phone airplane 1 0 0
UK red sms car 0 1 0
US green phone car 0 1 0
US red phone car 0 1 0
CA red sms car 0 1 0
US blue phone airplane 0 0 1
AU red phone car 0 0 1
AU blue phone train 0 0 1
这是一种方法,但可能不是最好的方法。就个人而言,我觉得这个列表不是您想要在 SSMS 中做的事情。而是在 Power BI 内部,Excel 或其他一些用于可视化数据而不是检索的软件。请注意,我下面的示例在有越来越多的星期的意义上并不是动态的。这特别适用于指定的 3 周。请参阅文档以查看哪个日期属于哪个星期。这是来自 SSMS v18.7.1
无论如何,这里是:
CREATE TABLE #list (
timestamp_ID datetime,
country varchar(255),
col1 varchar(255),
col2 varchar(255),
col3 varchar(255),
)
insert into #list (timestamp_ID, country, col1, col2, col3)
Values ('2021-01-04 11:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-04 11:00:00', 'US', 'red', 'sms', 'car'),
('2021-01-04 12:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-07 11:00:00', 'UK', 'red', 'phone', 'car'),
('2021-01-08 11:00:00', 'US', 'red', 'phone', 'airplane'),
('2021-01-11 11:00:00', 'UK', 'red', 'sms', 'car'),
('2021-01-11 11:00:00', 'US', 'green', 'phone', 'car'),
('2021-01-12 11:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-16 11:00:00', 'CA', 'red', 'sms', 'car'),
('2021-01-18 11:00:00', 'US', 'blue', 'phone', 'airplane'),
('2021-01-19 11:00:00', 'AU', 'red', 'phone', 'car'),
('2021-01-19 11:00:00', 'AU', 'blue', 'phone', 'train ');
select *, DATEPART(Week,a.timestamp_ID) As 'week'
into #week
from #list a
select a.country, a.col1, a.col2, a.col3, count(*) as 'Amount', a.week
into #filter
from #week a
group by a.country, a.col1, a.col2, a.col3, a.week
select a.country,
a.col1,
a.col2,
a.col3,
case when b.Amount is null then 0 else b.Amount end as 'Week 2',
case when c.Amount is null then 0 else c.Amount end as 'Week 3',
case when d.Amount is null then 0 else d.Amount end as 'Week 4'
from #week a
left join #filter b
on a.country=b.country and a.col1=b.col1 and a.col2=b.col2 and a.col3=b.col3 and b.week = 2
left join #filter c
on a.country=c.country and a.col1=c.col1 and a.col2=c.col2 and a.col3=c.col3 and c.week = 3
left join #filter d
on a.country=d.country and a.col1=d.col1 and a.col2=d.col2 and a.col3=d.col3 and d.week = 4
group by a.country, a.col1, a.col2, a.col3, b.Amount, c.Amount, d.Amount
drop table #list
drop table #filter
drop table #week
这在 Oracle DB 中有效。
create table damith.temp_test_01
(timestamp_ID TIMESTAMP,
Country varchar2(5),
col1 varchar2(8),
col2 varchar2(8),
col3 varchar2(10)
);
insert into damith.temp_test_01 values ( TIMESTAMP '2021-01-04 11:00:00' , 'US' ,'red','phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-04 11:00:00' , 'US','red','sms','car' );
insert into damith.temp_test_01 values ( TIMESTAMP '2021-01-04 12:00:00' , 'US','red', 'phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-07 11:00:00' , 'UK','red', 'phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-08 11:00:00' , 'US','red', 'phone', 'airplane' ) ;
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-11 11:00:00' , 'UK','red', 'sms', 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-11 11:00:00' , 'US','green', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-12 11:00:00' , 'US','red', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-16 11:00:00' , 'CA','red', 'sms' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-18 11:00:00' , 'US','blue', 'phone' , 'airplane' ) ;
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-19 11:00:00' , 'AU', 'red', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-19 11:00:00' , 'AU', 'blue', 'phone' , 'train' );
commit;
SELECT a.*, nvl(b.number_of_sale,0) as count_at_week_01,nvl(c.number_of_sale,0) as count_at_week_02,nvl(d.number_of_sale,0)
as count_at_week_03 ,nvl(e.number_of_sale,0)
as count_at_week_04 FROM
(SELECT distinct COUNTRY, COL1, COL2, COL3 FROM damith.temp_test_01)a left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 1
group by COUNTRY, COL1, COL2, COL3
)b on a.COUNTRY= b.COUNTRY and a.COL1= b.COL1 and a.COL2=b.COL2 and a.COL3=b.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 2
group by COUNTRY, COL1, COL2, COL3
)c on a.COUNTRY= c.COUNTRY and a.COL1= c.COL1 and a.COL2=c.COL2 and a.COL3=c.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 3
group by COUNTRY, COL1, COL2, COL3
)d on a.COUNTRY= d.COUNTRY and a.COL1= d.COL1 and a.COL2=d.COL2 and a.COL3=d.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 4
group by COUNTRY, COL1, COL2, COL3
)e on a.COUNTRY= e.COUNTRY and a.COL1= e.COL1 and a.COL2=e.COL2 and a.COL3=e.COL3
;
我有一个原创的table是这样的,
timestamp_ID Country col1 col2 col3
2021-01-04 11:00:00 US red phone car
2021-01-04 11:00:00 US red sms car
2021-01-04 12:00:00 US red phone car
2021-01-07 11:00:00 UK red phone car
2021-01-08 11:00:00 US red phone airplane
2021-01-11 11:00:00 UK red sms car
2021-01-11 11:00:00 US green phone car
2021-01-12 11:00:00 US red phone car
2021-01-16 11:00:00 CA red sms car
2021-01-18 11:00:00 US blue phone airplane
2021-01-19 11:00:00 AU red phone car
2021-01-19 11:00:00 AU blue phone train
我可以在 SQL 中使用 GROUP BY 对我的数据进行分组以获得每周的汇总值吗?
我的预期输出是这样的,
Country col1 col2 col3 count_at_week1(2021-01-04~2021-01-10) count_at_week2 count_at_week3 ...
US red phone car 2 0 0
US red sms car 1 0 0
UK red phone car 1 0 0
US red phone airplane 1 0 0
UK red sms car 0 1 0
US green phone car 0 1 0
US red phone car 0 1 0
CA red sms car 0 1 0
US blue phone airplane 0 0 1
AU red phone car 0 0 1
AU blue phone train 0 0 1
这是一种方法,但可能不是最好的方法。就个人而言,我觉得这个列表不是您想要在 SSMS 中做的事情。而是在 Power BI 内部,Excel 或其他一些用于可视化数据而不是检索的软件。请注意,我下面的示例在有越来越多的星期的意义上并不是动态的。这特别适用于指定的 3 周。请参阅文档以查看哪个日期属于哪个星期。这是来自 SSMS v18.7.1
无论如何,这里是:
CREATE TABLE #list (
timestamp_ID datetime,
country varchar(255),
col1 varchar(255),
col2 varchar(255),
col3 varchar(255),
)
insert into #list (timestamp_ID, country, col1, col2, col3)
Values ('2021-01-04 11:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-04 11:00:00', 'US', 'red', 'sms', 'car'),
('2021-01-04 12:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-07 11:00:00', 'UK', 'red', 'phone', 'car'),
('2021-01-08 11:00:00', 'US', 'red', 'phone', 'airplane'),
('2021-01-11 11:00:00', 'UK', 'red', 'sms', 'car'),
('2021-01-11 11:00:00', 'US', 'green', 'phone', 'car'),
('2021-01-12 11:00:00', 'US', 'red', 'phone', 'car'),
('2021-01-16 11:00:00', 'CA', 'red', 'sms', 'car'),
('2021-01-18 11:00:00', 'US', 'blue', 'phone', 'airplane'),
('2021-01-19 11:00:00', 'AU', 'red', 'phone', 'car'),
('2021-01-19 11:00:00', 'AU', 'blue', 'phone', 'train ');
select *, DATEPART(Week,a.timestamp_ID) As 'week'
into #week
from #list a
select a.country, a.col1, a.col2, a.col3, count(*) as 'Amount', a.week
into #filter
from #week a
group by a.country, a.col1, a.col2, a.col3, a.week
select a.country,
a.col1,
a.col2,
a.col3,
case when b.Amount is null then 0 else b.Amount end as 'Week 2',
case when c.Amount is null then 0 else c.Amount end as 'Week 3',
case when d.Amount is null then 0 else d.Amount end as 'Week 4'
from #week a
left join #filter b
on a.country=b.country and a.col1=b.col1 and a.col2=b.col2 and a.col3=b.col3 and b.week = 2
left join #filter c
on a.country=c.country and a.col1=c.col1 and a.col2=c.col2 and a.col3=c.col3 and c.week = 3
left join #filter d
on a.country=d.country and a.col1=d.col1 and a.col2=d.col2 and a.col3=d.col3 and d.week = 4
group by a.country, a.col1, a.col2, a.col3, b.Amount, c.Amount, d.Amount
drop table #list
drop table #filter
drop table #week
这在 Oracle DB 中有效。
create table damith.temp_test_01
(timestamp_ID TIMESTAMP,
Country varchar2(5),
col1 varchar2(8),
col2 varchar2(8),
col3 varchar2(10)
);
insert into damith.temp_test_01 values ( TIMESTAMP '2021-01-04 11:00:00' , 'US' ,'red','phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-04 11:00:00' , 'US','red','sms','car' );
insert into damith.temp_test_01 values ( TIMESTAMP '2021-01-04 12:00:00' , 'US','red', 'phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-07 11:00:00' , 'UK','red', 'phone','car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-08 11:00:00' , 'US','red', 'phone', 'airplane' ) ;
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-11 11:00:00' , 'UK','red', 'sms', 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-11 11:00:00' , 'US','green', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-12 11:00:00' , 'US','red', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-16 11:00:00' , 'CA','red', 'sms' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-18 11:00:00' , 'US','blue', 'phone' , 'airplane' ) ;
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-19 11:00:00' , 'AU', 'red', 'phone' , 'car' );
insert into damith.temp_test_01 values (TIMESTAMP '2021-01-19 11:00:00' , 'AU', 'blue', 'phone' , 'train' );
commit;
SELECT a.*, nvl(b.number_of_sale,0) as count_at_week_01,nvl(c.number_of_sale,0) as count_at_week_02,nvl(d.number_of_sale,0)
as count_at_week_03 ,nvl(e.number_of_sale,0)
as count_at_week_04 FROM
(SELECT distinct COUNTRY, COL1, COL2, COL3 FROM damith.temp_test_01)a left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 1
group by COUNTRY, COL1, COL2, COL3
)b on a.COUNTRY= b.COUNTRY and a.COL1= b.COL1 and a.COL2=b.COL2 and a.COL3=b.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 2
group by COUNTRY, COL1, COL2, COL3
)c on a.COUNTRY= c.COUNTRY and a.COL1= c.COL1 and a.COL2=c.COL2 and a.COL3=c.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 3
group by COUNTRY, COL1, COL2, COL3
)d on a.COUNTRY= d.COUNTRY and a.COL1= d.COL1 and a.COL2=d.COL2 and a.COL3=d.COL3
left outer join
(SELECT COUNTRY, COL1, COL2, COL3, count(*) as number_of_sale FROM damith.temp_test_01 where
to_char(timestamp_ID,'W') = 4
group by COUNTRY, COL1, COL2, COL3
)e on a.COUNTRY= e.COUNTRY and a.COL1= e.COL1 and a.COL2=e.COL2 and a.COL3=e.COL3
;