【问题标题】:SQL Server: grouping on rowsSQL Server:按行分组
【发布时间】:2020-12-28 21:47:43
【问题描述】:

我有如下数据:

我想将购买 = 1 的相同访问者的行和购买 = 0 的所有访问者的行分组。对于上述数据示例,应将行分组为:

  • 第 1 行和第 2 行应该组合在一起(因为 visit_id 1002 的购买 = 1,而 visit_id 1001 是购买之前的上一次访问,购买 = 0)
  • 第3行应该单独分组(因为visit_id 1003有purchase = 1,并且没有以前访问visit_id 1003有purchase = 0)(visit_id 1001不能被认为是visit_id 1003的上一次访问,因为visit_id 1002发生在1001之间和 1003 并且它有购买 = 1)
  • 第 4 行应单独分组(因为 visit_id 2001 之前没有任何访问)
  • 第 5,6 行和第 7 行应组合在一起(因为 visit_id 2004 的购买 = 1,而 visit_ids 2002 和 2003 是之前的访问,购买 = 0)

如何做到这一点?我正在使用 SQL Server 2012。

我期待类似于以下的输出:

生成上述数据的代码:

CREATE TABLE [#tmp_data]
(
    [visitor]       INT, 
    [visit_id]      INT, 
    [visit_time]    DATETIME, 
    [purchase]      BIT
);

INSERT INTO #tmp_data( visitor, visit_id, visit_time, purchase )
VALUES( 1, 1001, '2020-01-01 10:00:00', 0 ), 
( 1, 1002, '2020-01-02 11:00:00', 1 ), 
( 1, 1003, '2020-01-02 14:00:00', 1 ), 
( 2, 2001, '2020-01-01 10:00:00', 1 ), 
( 2, 2002, '2020-01-07 11:00:00', 0 ), 
( 2, 2003, '2020-01-08 14:00:00', 0 ), 
( 2, 2004, '2020-01-11 14:00:00', 1 );

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

我不确定您所说的“分组”是什么意思。但是您对分组的描述是1 值的数量在给定值上或之后。因此,这会为每个 visitor 分配一个值

select td.*,
       sum(case when purchase = 1 then 1 else 0 end) over (partition by visitor order by visit_time desc) as grouping
from #tmp_data td;

这可以简化为:

select td.*,
       sum( convert(int, purchase) ) over (partition by visitor order by visit_time desc) as grouping
from tmp_data td
order by visitor, visit_time;

注意:这只是分配一个“分组”。之后你可以随意聚合。

Here 是一个 dbfiddle。

【讨论】:

    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 2011-06-20
    • 2018-04-09
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    相关资源
    最近更新 更多