2

次のようなデータがあります。

+----+-------------------------+----------+----------+
| 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。しかし、以下の出力例のように隣接している限り、Quantityグループ化されたものを合計したいと思います。VendorID

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

私は現在、すべての行をロードし、アプリケーション コードでそれらを調べることでこれを行っています。これは現在、排除したい私のソフトウェアのボトルネックです。

目的の出力を生成するための MS SQL Server クエリとは何ですか?

PS。より良いタイトルの提案はありますか?

4

2 に答える 2

4

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 |
+----------+----------+
于 2013-10-24T19:02:34.157 に答える
2

この解決策を試してください:

SELECT  z.VendorID, z.GroupID,
        MIN(z.DateReceived) AS DateReceivedStart, 
        MAX(z.DateReceived) AS DateReceivedStop, 
        SUM(z.Quantity) AS SumOfQuantity
FROM
(
    SELECT  y.VendorID,
            y.RowNum1 - y.RowNum2 AS GroupID,
            y.DateReceived,
            y.Quantity
    FROM 
    (
        SELECT  *, ROW_NUMBER() OVER(ORDER BY x.DateReceived) AS RowNum1,
                   ROW_NUMBER() OVER(ORDER BY x.VendorID, x.DateReceived) AS RowNum2
        FROM    @MyTable x
    ) y
) z
GROUP BY z.VendorID, z.GroupID
ORDER BY DateReceivedStart

SQL フィドルのデモ

于 2013-10-24T19:17:24.757 に答える