简体   繁体   中英

SQL Group BY SUM one column and select of first row of grouped items

I have a part table where I have 5 fields. I want to sum the QTY of the mfgpn while showing the first returned row for the other 3 fields (Manfucturer, DateCode, Description). I initially thought of using the MIN function as follows, but that doesn't really help me insofar as that the data is not a int data type. How would I go about doing this? Right now I'm stuck at the following query below:

SELECT SUM([QTY]) AS QTY
  ,[MFGPN]
  ,MIN([MANUFACTURER]) AS MANUFACTURER
  ,MIN([DATECODE]) AS DateCode
  ,MIN([DESCRIPTION]) AS DESCRIPTION
  INTO part
GROUP BY MFGPN, MANUFACTURER, DATECODE, description
ORDER BY mfgpn ASC

Would CROSS APPLY work for you?

SELECT 
    SUM(a.[QTY]) AS QTY
    ,a.[MFGPN]
    ,c.[MANUFACTURER]
    ,c.[DATECODE]
    ,c.[DESCRIPTION]
FROM part a
    CROSS APPLY (SELECT TOP 1 * FROM part b WHERE a.[MFGPN] = b.[MFGPN]) c
GROUP BY 
    a.[MFGPN]
    ,c.[MANUFACTURER]
    ,c.[DATECODE]
    ,c.[DESCRIPTION]

Tested with the following:

DECLARE @T1 AS TABLE (
    [QTY] int
    ,[MFGPN] NVARCHAR(50)
    ,[MANUFACTURER] NVARCHAR(50)
    ,[DATECODE] DATE
    ,[DESCRIPTION] NVARCHAR(50));

INSERT @T1 VALUES
(2, 'MFGPN-1', 'MANUFACTURER-A', '20120101', 'A-1'),
(4, 'MFGPN-1', 'MANUFACTURER-B', '20120102', 'B-1'),
(3, 'MFGPN-1', 'MANUFACTURER-C', '20120103', 'C-1'),
(1, 'MFGPN-2', 'MANUFACTURER-A', '20120101', 'A-2'),
(5, 'MFGPN-2', 'MANUFACTURER-B', '20120101', 'B-2')

SELECT 
    SUM(a.[QTY]) AS QTY
    ,a.[MFGPN]
    ,c.[MANUFACTURER]
    ,c.[DATECODE]
    ,c.[DESCRIPTION]
FROM @T1 a
    CROSS APPLY (SELECT TOP 1 * FROM @T1 b WHERE a.[MFGPN] = b.[MFGPN]) c
GROUP BY 
    a.[MFGPN]
    ,c.[MANUFACTURER]
    ,c.[DATECODE]
    ,c.[DESCRIPTION]

Produces

QTY MFGPN   MANUFACTURER    DATECODE    DESCRIPTION
9   MFGPN-1 MANUFACTURER-A  2012-01-01  A-1
6   MFGPN-2 MANUFACTURER-A  2012-01-01  A-2

This can be easily managed with a windowed SUM() :

WITH summed_and_ranked AS (
  SELECT
    MFGPN,
    MANUFACTURER,
    DATECODE,
    DESCRIPTION,
    QTY = SUM(QTY) OVER (PARTITION BY MFGPN),
    RNK = ROW_NUMBER() OVER (
      PARTITION BY MFGPN
      ORDER BY DATECODE  -- or which column should define the order?
    )
  FROM atable
)
SELECT
  MFGPN,
  MANUFACTURER,
  DATECODE,
  DESCRIPTION,
  QTY,
INTO parts
FROM summed_and_ranked
WHERE RNK = 1
;

For every row, the total group quantity and the ranking within the group is calculated. When actually getting rows for inserting into the new table (the main SELECT), only rows with RNK values of 1 are pulled. Thus you get a result set containing group totals as well as details of certain rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM