T-SQL - 使用相关子查询的聚合来聚合所有行

发布于 2025-01-08 03:04:35 字数 818 浏览 0 评论 0原文

store   item   datekey   onhand   salesunits
--------------------------------------------
001     A      50        65       2
001     A      51        8        4
001     A      52        0        8
--------------------------------------------

我需要完成的任务是:按商店和商品获取大于零减去已售总单位数的最新库存。所以在上面的例子中它将是 8-14=-6。

我使用相关子查询来确定最新的日期键,然后连接回主查询。但显然这样做我会丢失与销售单位求和所需的其他行相关的数据:

这就是我所拥有的,这是错误的:

select s1.Store, s1.Item, s1.OnHand, sum(salesunit)
from sales s1
  join (select top 1 store,item, max(DateKey) as datekey
        from sales
        where isnull(onhand,0) > 0
          and DateKey in (50,51,52)
        group by store, item) s2  on s2.store=s1.store and s2.item=s1.item and s2.datekey=s1.datekey
group by s1.Store, s1.Item, s1.OnHand

感谢您的帮助!

store   item   datekey   onhand   salesunits
--------------------------------------------
001     A      50        65       2
001     A      51        8        4
001     A      52        0        8
--------------------------------------------

What I need to accomplish: to get the latest onhand greater than zero minus the total units sold, by store and item. So in the example above it would be 8-14=-6.

I am using a correlated sub-query to determine the latest datekey and then joining back to the main query. But obviously by doing so I lose the data related to the other rows necessary to sum the salesunits:

This is what I have and it's wrong:

select s1.Store, s1.Item, s1.OnHand, sum(salesunit)
from sales s1
  join (select top 1 store,item, max(DateKey) as datekey
        from sales
        where isnull(onhand,0) > 0
          and DateKey in (50,51,52)
        group by store, item) s2  on s2.store=s1.store and s2.item=s1.item and s2.datekey=s1.datekey
group by s1.Store, s1.Item, s1.OnHand

Thanks for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

傾城如夢未必闌珊 2025-01-15 03:04:35
;
WITH totals AS (
  SELECT
    *,
    totalsalesunits = SUM(salesunits) OVER (PARTITION BY store, item),
    rnk = ROW_NUMBER() OVER (PARTITION BY store, item
                                 ORDER BY SIGN(onhand) DESC, datekey DESC)
  FROM sales
)
SELECT
  store,
  item,
  onhand,
  totalsalesunits
FROM totals
WHERE rnk = 1
;
WITH totals AS (
  SELECT
    *,
    totalsalesunits = SUM(salesunits) OVER (PARTITION BY store, item),
    rnk = ROW_NUMBER() OVER (PARTITION BY store, item
                                 ORDER BY SIGN(onhand) DESC, datekey DESC)
  FROM sales
)
SELECT
  store,
  item,
  onhand,
  totalsalesunits
FROM totals
WHERE rnk = 1
病毒体 2025-01-15 03:04:35

我会这样做:

首先一些测试数据:

DECLARE @tbl TABLE
        (
            store VARCHAR(4),
            item VARCHAR(2),
            datekey INT,
            onhand INT,
            salesUnits INT
        )

INSERT INTO @tbl
VALUES
    ('001','A',50,65,2),
    ('001','A',51,8,4),
    ('001','A',52,0,8)

查询如下:

;WITH cteTotalSales AS
(
    SELECT
        SUM(tbl.salesUnits) OVER(PARTITION BY 1) AS TotalSalesUnit,
        tbl.store,
        tbl.item,
        ISNULL(tbl.onhand,0) AS onhand,
        tbl.salesUnits,
        tbl.datekey
    FROM
        @tbl AS tbl
), cteLatest AS
(
    SELECT
        RANK() OVER
            (
                PARTITION BY cteTotalSales.store,cteTotalSales.item 
                ORDER BY cteTotalSales.datekey DESC
            ) AS iRank,
        cteTotalSales.store,
        cteTotalSales.item,
        cteTotalSales.onhand,
        cteTotalSales.salesUnits,
        cteTotalSales.datekey
    FROM
        cteTotalSales
    WHERE
        (cteTotalSales.onhand-cteTotalSales.TotalSalesUnit)>0
)
SELECT
    *
FROM
    cteLatest
WHERE
    iRank=1

I would do it something like this:

First some test data:

DECLARE @tbl TABLE
        (
            store VARCHAR(4),
            item VARCHAR(2),
            datekey INT,
            onhand INT,
            salesUnits INT
        )

INSERT INTO @tbl
VALUES
    ('001','A',50,65,2),
    ('001','A',51,8,4),
    ('001','A',52,0,8)

The the query like this:

;WITH cteTotalSales AS
(
    SELECT
        SUM(tbl.salesUnits) OVER(PARTITION BY 1) AS TotalSalesUnit,
        tbl.store,
        tbl.item,
        ISNULL(tbl.onhand,0) AS onhand,
        tbl.salesUnits,
        tbl.datekey
    FROM
        @tbl AS tbl
), cteLatest AS
(
    SELECT
        RANK() OVER
            (
                PARTITION BY cteTotalSales.store,cteTotalSales.item 
                ORDER BY cteTotalSales.datekey DESC
            ) AS iRank,
        cteTotalSales.store,
        cteTotalSales.item,
        cteTotalSales.onhand,
        cteTotalSales.salesUnits,
        cteTotalSales.datekey
    FROM
        cteTotalSales
    WHERE
        (cteTotalSales.onhand-cteTotalSales.TotalSalesUnit)>0
)
SELECT
    *
FROM
    cteLatest
WHERE
    iRank=1
等往事风中吹 2025-01-15 03:04:35
;with a as
(
select rn = row_number() over (partition by store, item order by case when onhand = 0 then -1 else datekey end desc), 
Store, Item, OnHand, salesunit
from sales
)
select store, item, sum(case when rn = 1 then onhand end)-sum(salesunit) OnHand, sum(salesunit) sumsalesunit from a
group by store, item
;with a as
(
select rn = row_number() over (partition by store, item order by case when onhand = 0 then -1 else datekey end desc), 
Store, Item, OnHand, salesunit
from sales
)
select store, item, sum(case when rn = 1 then onhand end)-sum(salesunit) OnHand, sum(salesunit) sumsalesunit from a
group by store, item
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文