如何按过去几周对数据进行分组?

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
;