【问题标题】:How to eliminate a row which having the maximum ID in sql query?如何消除sql查询中具有最大ID的行?
【发布时间】:2019-11-30 06:36:39
【问题描述】:

我需要从 sql 查询中删除具有最大 ID 的最后一行。我该怎么做?我尝试以下查询。但它没有生成记录

SELECT a.DocEntry, a.Project, a.DocTotal, a.U_Installement
FROM OPCH AS a
LEFT JOIN PCH1 AS b
    ON b.DocEntry = a.DocEntry
LEFT JOIN OPOR AS c
    ON c.DocEntry = b.BaseEntry
    AND a.Project = c.Project
WHERE a.CANCELED = 'N'
AND a.Project = c.Project
GROUP BY a.DocEntry, a.Project, a.DocTotal, a.U_Installement
HAVING MAX(a.DocEntry) <> a.DocEntry;

【问题讨论】:

标签: sql sql-server


【解决方案1】:

看起来这样可行:

SELECT a.DocEntry, a.Project, a.DocTotal, a.U_Installement
FROM OPCH AS a
  JOIN PCH1 AS b
    ON b.DocEntry = a.DocEntry
  JOIN OPOR AS c
    ON c.DocEntry = b.BaseEntry
    AND a.Project = c.Project
WHERE a.CANCELED = 'N'
    AND a.DocEntry NOT IN (SELECT MAX(DocEntry) FROM OPCH)

【讨论】:

  • 不妨将a.Project = c.Project 移动到ON 并将2 个连接也更改为INNER JOIN;将 JOIN 保留为 OPORLEFT JOIN 并且不将其更改为 INNER JOIN 将在您将子句移动到 ON 时更改查询行为。
  • @Larnu,谢谢,没错,我已经确定了答案
  • @Renat 。 . .这将起作用,因为最大条目可能会被其他条件过滤掉。
【解决方案2】:

在我看来,您想消除每个组的最大 ID,因此我使用了 row_number()

    with cte as
    (

    SELECT a.DocEntry, a.Project, a.DocTotal, a.U_Installement,
     row_number()over(partitioned by a.Project, a.DocTotal, a.U_Installement
      ordere by a.DocEntry desc) rn
    FROM OPCH AS a
    JOIN PCH1 AS b
        ON b.DocEntry = a.DocEntry
     JOIN OPOR AS c
        ON c.DocEntry = b.BaseEntry
        AND a.Project = c.Project
    WHERE a.CANCELED = 'N'

 ) select * from cte where rn<>1

【讨论】:

  • 由于OPORON 中的c.DocEntry = b.BaseEntry 子句,在隐含的INNER JOIN 中也加入了PCH1。根据 OP 查询中的逻辑,OPOR 中必须有一行,所以不妨将它们都设为INNER JOIN
【解决方案3】:

首先,学会使用有意义的表别名而不是任意字母。这使查询更易于阅读。

其次,您的 WHERE 子句将外连接变为内连接。

然后,您将删除重复项——但这些可能是由JOINs 生成的。这可以通过使用EXISTS 来解决。

所以对于您的完整查询:

SELECT o.DocEntry, o.Project, o.DocTotal, o.U_Installement
FROM OPCH o
WHERE o.CANCELED = 'N' AND
      EXISTS (SELECT 1
              FROM PCH1 p JOIN
                   OPOR op
                   ON op.DocEntry = p.BaseEntry
              WHERE p.DocEntry = o.DocEntry AND
                    op.Project = o.Project
             );

然后,您可以将窗口函数合并到此:

SELECT DocEntry, Project, DocTotal, U_Installement
FROM (SELECT o.DocEntry, o.Project, o.DocTotal, o.U_Installement,
             MAX(o.DocEntry) OVER () as max_DocEntry
      FROM OPCH o
      WHERE o.CANCELED = 'N' AND
            EXISTS (SELECT 1
                    FROM PCH1 p JOIN
                         OPOR op
                         ON op.DocEntry = p.BaseEntry
                    WHERE p.DocEntry = o.DocEntry AND
                          op.Project = o.Project
                   )
     ) o
WHERE docEntry < max_docEntry;

【讨论】:

    【解决方案4】:

    我们经常使用这种方法:

    select a.* from ( 
        SELECT a.DocEntry, a.Project, a.DocTotal, a.U_Installement
        FROM OPCH a 
        GROUP BY a.DocEntry, a.Project, a.DocTotal, a.U_Installement
        HAVING MAX(a.DocEntry) <> a.DocEntry 
    ) AS a 
    LEFT JOIN PCH1 AS b
        ON b.DocEntry = a.DocEntry
    LEFT JOIN OPOR AS c
        ON c.DocEntry = b.BaseEntry
        AND a.Project = c.Project
    WHERE a.CANCELED = 'N'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 2020-03-29
      • 1970-01-01
      • 2018-08-17
      相关资源
      最近更新 更多