【问题标题】:Grouping in SELECT statement with two columns that contain different values among rows在 SELECT 语句中分组,两列在行之间包含不同的值
【发布时间】:2013-11-29 19:32:09
【问题描述】:

我有一个 SQL 查询,我正在对一些表 SQL Server 数据库执行。结果集如下所示:

Column1 | Column2 | Column3 | InvoiceNumber | InvoiceID
-------------------------------------------------------
1        1         1          1234            1
1        1         1          5678            2

我只想取回具有最小 InvoiceID 的行及其对应的 InvoiceNumber。

我在 SELECT 语句中应用min(InvoiceID)。在 GROUP BY 子句中,我按除 InvoiceNumber 和 InvoiceID 之外的每一列进行分组。我收到一个错误,因为 InvoiceNumber 不包含在 SELECT 语句的聚合函数中,也不存在于 GROUP BY 子句中。

如何构造查询,以便只取回具有最小 InvoiceID 和相应 InvoiceNumber 的行?

编辑

以下是一些附加信息:

结果集实际上将包含许多行。只是偶尔,多行的 Column1、Column2 和 Column3 的值相同,但 InvoiceNumber 和 InvoiceID 的值不同。因此,结果集的更好示例如下所示:

Column1 | Column2 | Column3 | InvoiceNumber | InvoiceID
-------------------------------------------------------
1        1         1          1234            1
1        1         1          5678            2
2        1         1          1287            3
2        1         2          1287            3
2        2         1          1287            3
3        1         1          5555            4
3        1         2          5555            4

所以当 Column1、Column2 和 Column3 相同时,我只想要具有最小 InvoiceID 的结果,以及具有最小 InvoiceID 的行的 InvoiceNumber 是什么。在这种情况下,我希望它看起来像这样:

Column1 | Column2 | Column3 | InvoiceNumber | InvoiceID
-------------------------------------------------------
1        1         1          1234            1
2        1         1          1287            3
2        1         2          1287            3
2        2         1          1287            3
3        1         1          5555            4
3        1         2          5555            4

仅删除了第二行,因为它的 InvoiceID 较小,并且是唯一与不同行的 Column1、Column2 和 Column3 具有相同值的行。

这是我的 SQL 查询当前的样子:

SELECT c.CollectionID
    , p.Account
    , d.TransactionID
    , id.InvoiceNumber
    , i.InvoiceID
FROM collection c
INNER JOIN documents d on c.GlobalCollectionID = d.GlobalCollectionID
LEFT JOIN payment p on c.GlobalCollectionID = p.GlobalCollectionID
    AND d.TransactionID = p.TransactionID
LEFT JOIN invoice i on c.GlobalCollectionID = i.GlobalCollectionID
    AND d.TransactionID = i.TransactionID
LEFT JOIN invoicedata id on i.InvoiceID = id.InvoiceID
WHERE c.ProcessDate = '2013-11-29'
    AND c.Item = 11805123
    AND c.CollectionID in ('1104', '1105', '1106')
ORDER BY c.CollectionID
    , d.TransactionID
    , i.InvoiceID
    , p.Account

【问题讨论】:

    标签: sql sql-server group-by


    【解决方案1】:

    如果您将 SQL 发布到初始查询中,可能会更容易提供帮助。

    您可能希望将您的 MIN() 函数移动到 WHERE 子句中:

    SELECT Column1 ,Column2 ,Column3 ,InvoiceNumber , InvoiceID
    FROM Table_Name
    WHERE InvoiceID = (SELECT MIN(InvoiceID) FROM Table_Name)
    

    【讨论】:

      【解决方案2】:

      现在你已经提供了一些数据,并且已经用这个新数据和新要求改变了你的要求,试试这个

      DECLARE @T Table (Column1 INT,Column2 INT,Column3 INT,InvoiceNumber INT, InvoiceID INT)
      
      INSERT INTO @T
      VALUES
      (1,1,1,1234,1),
      (1,1,1,5678,2),
      (2,1,1,1287,3),
      (2,1,2,1287,3),
      (2,2,1,1287,3),
      (3,1,1,5555,4),
      (3,1,2,5555,4)
      
      ;WITH CTE
       AS
         (
         SELECT Column1 ,Column2 
                ,Column3 ,InvoiceNumber , InvoiceID 
                , rn = ROW_NUMBER() OVER (PARTITION BY Column1 ,Column2 ,Column3  ORDER BY InvoiceID ASC)
         FROM @T
         )
       SELECT * FROM CTE
       WHERE rn = 1
      

      结果集

      Column1 Column2 Column3 InvoiceNumber   InvoiceID   rn
         1       1       1    1234               1        1
         2       1       1    1287               3        1
         2       1       2    1287               3        1
         2       2       1    1287               3        1
         3       1       1    5555               4        1
         3       1       2    5555               4        1
      

      您的查询

      ;WITH CTE
       AS
         (
          SELECT YourQuery.* 
          , rn = ROW_NUMBER() OVER (PARTITION BY c.CollectionID , p.Account , d.TransactionID ORDER BY InvoiceID ASC)
          ( 
           SELECT c.CollectionID
              , p.Account
              , d.TransactionID
              , id.InvoiceNumber
              , i.InvoiceID
          FROM collection c
          INNER JOIN documents d on c.GlobalCollectionID = d.GlobalCollectionID
          LEFT JOIN payment p on c.GlobalCollectionID = p.GlobalCollectionID
              AND d.TransactionID = p.TransactionID
          LEFT JOIN invoice i on c.GlobalCollectionID = i.GlobalCollectionID
              AND d.TransactionID = i.TransactionID
          LEFT JOIN invoicedata id on i.InvoiceID = id.InvoiceID
          WHERE c.ProcessDate = '2013-11-29'
              AND c.Item = 11805123
              AND c.CollectionID in ('1104', '1105', '1106')
            )YourQuery
         )
       SELECT C.CollectionID , C.Account , C.TransactionID,C.InvoiceNumber, C.InvoiceID 
       FROM CTE C
       WHERE rn = 1
      

      【讨论】:

        【解决方案3】:

        这是您要查找的查询:

        SELECT Column1, Column2, Column3, InvoiceNumber, InvoiceID
        FROM ( 
            SELECT *,
                rn = ROW_NUMBER() OVER (PARTITION BY Column1, Column2, Column3
                                        ORDER BY InvoiceID ASC)
            FROM example
        ) e
        WHERE rn = 1
        

        查看它在 SQLFiddle 上的工作。只需将您的查询换成嵌套查询,但保留 ROW_NUMBER 字段。

        产生正确的结果集:

        COLUMN1  COLUMN2  COLUMN3  INVOICENUMBER   INVOICEID
        ----------------------------------------------------
        1        1        1        1234            1
        2        1        1        1287            3
        2        1        2        1287            3
        2        2        1        1287            3
        3        1        1        5555            4
        3        1        2        5555            4
        

        【讨论】:

          猜你喜欢
          • 2020-10-15
          • 2013-10-18
          • 2020-12-19
          • 2011-08-18
          • 1970-01-01
          • 2013-01-29
          • 2018-08-31
          • 1970-01-01
          • 2021-04-15
          相关资源
          最近更新 更多