按连续外键​​值分组的 SQL 查询

标签 sql sql-server

我有这样的数据:

+----+-------------------------+----------+----------+
| ID |      DateReceived       | Quantity | VendorID |
+----+-------------------------+----------+----------+
|  1 | 2010-08-09 06:53:44.783 |        2 |        1 |
|  2 | 2010-08-01 13:31:26.893 |        1 |        1 |
|  3 | 2010-07-26 07:52:29.403 |        2 |        1 |
|  4 | 2011-03-22 13:31:11.000 |        1 |        2 |
|  5 | 2011-03-22 13:31:11.000 |        1 |        2 |
|  6 | 2011-03-22 11:27:01.000 |        1 |        2 |
|  7 | 2011-03-18 09:04:58.000 |        1 |        1 |
|  8 | 2011-12-17 08:21:29.000 |        1 |        3 |
|  9 | 2012-08-10 10:55:20.000 |        9 |        3 |
| 10 | 2012-08-02 20:18:10.000 |        5 |        1 |
| 11 | 2012-07-12 20:44:36.000 |        3 |        1 |
| 12 | 2012-07-05 20:45:29.000 |        1 |        1 |
| 13 | 2013-03-22 13:31:11.000 |        1 |        2 |
| 14 | 2013-03-22 13:31:11.000 |        1 |        2 |
+----+-------------------------+----------+----------+

我想按 DateReceived 对数据进行排序并对 Quantity 求和。但是,我想对按 VendorID 分组的 Quantity 求和,只要它们像下面的示例输出那样相邻即可。

+----------+----------+
| VendorID | Quantity |
+----------+----------+
|        1 |        5 |
|        2 |        3 |
|        1 |        1 |
|        3 |       10 |
|        1 |        9 |
|        2 |        2 |
+----------+----------+

我目前正在通过加载所有行并在我的应用程序代码中遍历它们来执行此操作。这是目前我想要消除的软件瓶颈。

生成所需输出的 ​​MS Sql Server 查询是什么?

附言。对更好的标题有什么建议吗?

最佳答案

SQL Server 2005+ 中,您可以这样做:

with cte as (
    select
        VendorID, Quantity,
        row_number() over(partition by VendorID order by DateReceived) as rn1,
        row_number() over(order by DateReceived) as rn2
    from Table1
)
select
    VendorID, sum(Quantity) as Quantity
from cte 
group by VendorID, rn2 - rn1
order by min(rn2)

sql fiddle demo

SQL Server 2012 中,您可以使用 lag() 函数:

with cte as (
    select
        VendorID, Quantity, DateReceived,
        case when lag(VendorID) over(order by DateReceived) <> VendorID then 1 else 0 end as rn
    from Table1
), cte2 as (
    select
        VendorID, Quantity, sum(rn) over(order by DateReceived) as s
    from cte 
)
select
    VendorID, sum(Quantity)
from cte2
group by VendorID, s
order by s asc

sql fiddle demo

顺便说一句,看起来你的输出不正确。正确的是:

+----------+----------+
| VendorID | Quantity |
+----------+----------+
|        1 |        6 |
|        2 |        3 |
|        3 |        1 |
|        1 |        9 |
|        3 |        9 |
|        2 |        2 |
+----------+----------+

关于按连续外键​​值分组的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19573892/

相关文章:

mysql - 如何获取按一列过滤的 MySQL 行

Python、Qt、ComboBox、两栏?

sql - 至少一个子级具有其所有子级的所有行都通过条件

sql - 从 SQL Server 中的 VARCHAR 中删除非数字字符的最快方法

sql - 优化在 Oracle 上运行缓慢而在 SQL Server 上运行快速的 SELECT 查询

.net - 您可以/应该将 SQL Server Service Broker 与 .NET 应用程序一起使用吗?

sql - 触发更新现有数据或在数据不存在时插入(多行支持)

sql - 更改要计算的列 SQL SERVER

php - 'group' 列以某种方式导致语法错误

SQL查询两次返回同一行数据