SQL:每个分组取1个值

SQL:每个分组取1个值,sql,sql-server,Sql,Sql Server,我有一个非常简化的表/视图,如下所示,以说明该问题: stock列表示该款式在零售商的当前库存量。包含stock列的原因是为了避免报告的联接。(创建该表仅用于报告) 我想查询该表以获得当前的库存,按stylenumber(跨零售商)分组。比如: 我希望获得Stylenumber、总销售额、最近的库存总额: A、 6,15 B、 1,6 但是用…Max(股票)我得到10,用(总和)我得到25。。。。 我尝试过(分区…)也没有任何运气 如何解决此问题?查询有点棘手,因为您需要的是已售出列的累计

我有一个非常简化的表/视图,如下所示,以说明该问题:

stock
列表示该款式在零售商的当前库存量。包含
stock
列的原因是为了避免报告的联接。(创建该表仅用于报告)

我想查询该表以获得当前的库存,按stylenumber(跨零售商)分组。比如:

我希望获得Stylenumber、总销售额、最近的库存总额:

  • A、 6,15
  • B、 1,6
但是用…Max(股票)我得到10,用(总和)我得到25。。。。 我尝试过(分区…)也没有任何运气


如何解决此问题?

查询有点棘手,因为您需要的是
已售出
列的累计总数,而仅是最近日期的
库存
列的总数。我实际上没有尝试运行这个,但是下面的查询应该可以运行。但是,由于模式的形状,这并不是世界上性能最好的查询,因为它多次扫描您的表以将所有数据连接在一起:

SELECT      MDate.Stylenumber, MDate.TotalSold, MStock.TotalStock
FROM        (SELECT M.Stylenumber, MAX(M.Date) MostRecentDate, SUM(M.Sold) TotalSold
            FROM    [MGTest] M
            GROUP BY    M.Stylenumber) MDate
INNER JOIN  (SELECT M.Stylenumber, M.Date, SUM(M.Stock) TotalStock
            FROM    [MGTest] M
            GROUP BY    M.Stylenumber, M.Date) MStock ON MDate.Stylenumber = MStock.Stylenumber AND MDate.MostRecentDate = MStock.Date

你可以这样做

SELECT B.Stylenumber,SUM(B.Sold),SUM(B.Stock) FROM
(SELECT Stylenumber AS 'Stylenumber',SUM(Sold) AS 'Sold',MAX(Stock) AS 'Stock'
FROM MGTest A
GROUP BY RetailerId,Stylenumber) B
GROUP BY B.Stylenumber 

如果您不想使用联接,我将使用窗口函数回答:

SELECT Stylenumber, Date, TotalStock
FROM (SELECT M.Stylenumber, M.Date, SUM(M.Stock) as TotalStock,
             ROW_NUMBER() OVER (PARTITION BY M.Stylenumber ORDER BY M.Date DESC) as seqnum
      FROM MGTest M
      GROUP BY M.Stylenumber, M.Date
     ) m
WHERE seqnum = 1;

我的解决方案,如Gordon Linoff的解决方案,将使用窗口函数。但在我的例子中,一切都将改变排名窗口函数

SELECT stylenumber, sold, SUM(stock) totalstock
FROM (
  SELECT
    stylenumber,
    SUM(sold) OVER(PARTITION BY stylenumber) sold,
    RANK() OVER(PARTITION BY stylenumber ORDER BY [Date] DESC) r,
    stock
  FROM MGTest
) T
WHERE r = 1
GROUP BY stylenumber, sold

您必须根据样式号和日期对第一组进行分组。然后必须使用STUFF和FOR XML来获取分隔值。这里的输出充其量是有问题的,因为分隔数据通常比它需要的更痛苦;6.15?我猜6来自你的Stylenumber(1+3+2)的sum of Seld列,但是15?你是怎么得到的?15来自10(来自零售商123)+5(来自零售商456)@SeanLange:输出不应该被分隔。。。只是想展示我的预期结果;)输出为普通列,但结果中没有RetailerID。你怎么知道你只想要RetailerID 123(而不是RetailerID 456)的stlyNumber A?我认为你的查询无法正确计算库存,因为它只查看最大库存值,而不是最新日期的库存值。@sam2929 OP从未提到他需要基于日期的库存。。是吗?不是很明确,但从评论中的OPs回应和问题中提供的预期结果来看,这似乎是我们想要的。OP在对我的回答的评论中也证实了这一点。@sam2929,只是为了对我有利。。。在我回答7分钟后,他对你的回答做出了回应p你对这个问题的描述比我所能描述的更清楚(累计总数vs最近的总数)。。。我明白建议的解决方案的要点,但您在扫描表格时是对的。@MortenV.Gade很高兴听到您正试图传达这一点。如果此回答回答了您的问题,请将其标记为结束您的问题的答案。
SELECT stylenumber, sold, SUM(stock) totalstock
FROM (
  SELECT
    stylenumber,
    SUM(sold) OVER(PARTITION BY stylenumber) sold,
    RANK() OVER(PARTITION BY stylenumber ORDER BY [Date] DESC) r,
    stock
  FROM MGTest
) T
WHERE r = 1
GROUP BY stylenumber, sold