带有 WHERE 子句和 MAX 函数的 SQL 选择

SQL select with WHERE clause and MAX function

提问人:user11654732 提问时间:9/29/2020 最后编辑:sticky bituser11654732 更新时间:9/29/2020 访问量:1224

问:

我见过类似的问题,但没有一个涉及许多 WHERE 子句。

有没有更有效的方法来实现以下目标(z/OS 上的 DB2),理想情况下没有重复 WHERE 子句?

SELECT *
FROM     TABLE

WHERE     Value1        =   "A"
   AND    Value2        =   "B"
   AND    Tran-No       =    123
   AND    Seq-No        =  (SELECT MAX(Seq-No)

                              FROM Table

                             WHERE    Value1        =  "A"
                               AND    Value2        =  "B"
                               AND    Tran-No       =  123)

基本上有许多行与“WHERE”条件匹配,并且只应返回具有最高 Seq-No 的行。上述方法有效,但有更好的选择吗?

SQL DB2 WHERE-子句

评论


答:

0赞 Paul T. 9/29/2020 #1

似乎你可以做:

  SELECT Seq-No
    FROM TABLE
   WHERE Value1  = "A"
     AND Value2  = "B"
     AND Tran-No = 123
ORDER BY Seq-No DESC
   LIMIT 1

为了获得第一个最高值?Seq-No

0赞 sticky bit 9/29/2020 #2

您可以使用 CTE。

WITH
cte
AS
(
SELECT *
       FROM "TABLE"
       WHERE "Value1" = 'A'
             AND "Value2" = 'B'
             AND "Tran-No" = 123
)
SELECT *
       FROM cte
       WHERE "Seq-No" = (SELECT max("Seq-No")
                                FROM cte);

注意:不要用双引号引号引用字符串文字(我假设并且不是列名)。字符串文字在 SQL 中用单引号括起来。即使您的 DBMS 也接受双引号,仅使用单引号也更不容易出错且更便于移植。双引号用于引用带有特殊字符、保留/关键字的标识符或强制区分大小写。至少对于包含 和 的列名,您至少需要它。如果大小写很重要,也许也适用于其他标识符(如果不是,请将其从中删除)。AB-TABLE

0赞 Bik Dhaliwal 9/29/2020 #3

您也可以使用排名功能

选择 * FROM ( SELECT Seq-No, Value1, Value2, Trans-No, RANK() OVER (ORDER BY Seq-No DESC) AS SeqRank FROM 表,其中 Value1 = “A” 和 Value2 = “B” 和 Trans-No=123 ) 其中 SeqRank = 1

inner-select 语句将根据列条件结果的 ORDER BY 对 1..N 以上的行进行排名。仍然涉及排序,但是 RANK() 在多个 RDBMS 系统中得到广泛支持,并且在此示例之外还有其他用途。

0赞 Gordon Linoff 9/29/2020 #4

我猜您希望每个值组合一行。这表明:row_number()

select t.*
from (select t.*,
             row_number() over (partition by value1, value2, tran_no order by seq_no desc) as seqnum
      from t
     ) t
where value1 = 'A' and value2 = 'B' and trans_no = 1;

但是,如果您真的想要一行,则不需要子查询:

select t.*
from t
where value1 = 'A' and value2 = 'B' and trans_no = 1
order by seq_no
fetch first 1 row only;