DB2 和 SQL-如何在特定字段中返回最大值,以便每行只显示一条记录;从多个表中提取数据

Posted

技术标签:

【中文标题】DB2 和 SQL-如何在特定字段中返回最大值,以便每行只显示一条记录;从多个表中提取数据【英文标题】:DB2 and SQL-How to return max value in a particular field so that only one record shows up per row; pulling data from multiple tables 【发布时间】:2014-03-18 20:55:08 【问题描述】:

所有, 下面的数据集从三个单独的表中提取了 WONO、EPLSNM 和 SQNO1。我需要的是一个 db2 sql 查询,它将返回每个唯一 WONO 的员工姓名 (EPLSNM),最大 SQNO1。

WONO    EPLSNM               SQNO1
CA04269 WILLIAMS, BILLY W   12
CA04269 WILLIAMS, BILLY W   12
CA04269 WILLIAMS, BILLY W   12
CA04269 WILLIAMS, BILLY W   12
CA04270 FAIRCLOTH, MARK E   22
CA04270 FAIRCLOTH, MARK E   22
CA04270 FAIRCLOTH, MARK E   22
CA04270 FAIRCLOTH, MARK E   22
CA04270 FAIRCLOTH, MARK E   23
CA04270 FAIRCLOTH, MARK E   23
CA04270 FAIRCLOTH, MARK E   23
CA04270 FAIRCLOTH, MARK E   23

如果可能,我希望看到以下内容:

WONO    EPLSNM               SQNO1
CA04269 WILLIAMS, BILLY W   12
CA04270 FAIRCLOTH, MARK E       23

我只需要 2 行数据而不是我得到的 12 行数据。

非常感谢。

这是我的代码:

    SELECT DISTINCT WOHDR.wono,EMP.eplsnm,max(WOLBR.sqno1) AS SQNO,WOLBR.cgcd,CASE WHEN WOHDR.opndt8 IN (' ') THEN DATE('1900-01-01') WHEN WOHDR.opndt8 IS NULL THEN DATE('1900-01-01') ELSE Date(Cast(SUBSTRING(WOHDR.opndt8,1,4) as char(4)) ||'-'|| Cast(SUBSTRING(WOHDR.opndt8,5,2) as char(2)) ||'-'|| Cast(SUBSTRING(WOHDR.opndt8,7,2) as char(2))) END AS OpenDate,CASE WHEN WOHDR.prmdt8 IN (' ') THEN DATE('1900-01-01') WHEN WOHDR.prmdt8 IS NULL THEN DATE('1900-01-01') ELSE Date(Cast(SUBSTRING(WOHDR.prmdt8,1,4) as char(4)) ||'-'|| Cast(SUBSTRING(WOHDR.prmdt8,5,2) as char(2)) ||'-'|| Cast(SUBSTRING(WOHDR.prmdt8,7,2) as char(2))) END AS PromisedDate,WOHDR.divi AS Division, WOHDR.cunm AS CustName, WOHDR.eqmfmd AS Model,WOHDR.stno AS StoreNo,RPT.ds5 AS StoreName,WOHDR.acti

FROM libd09.wophdrs0 WOHDR 
JOIN libd09.wopsegs0 WOSEG ON (WOHDR.wono = WOSEG.wono)
JOIN libd09.fnlrlvl0 RPT ON (WOHDR.stno = RPT.st4 AND WOHDR.stno = WOSEG.stn1)
LEFT JOIN libd09.cipname0 NME ON (NME.cuno = WOHDR.cuno)
LEFT JOIN libd09.woplabr0 WOLBR ON (WOHDR.wono = WOLBR.wono)
LEFT JOIN libd09.wopempf0 EMP ON (EMP.epidno = WOLBR.epidno AND WOHDR.stno = EMP.stn1)
WHERE WOHDR.opndt8 BETWEEN 20130101 AND YEAR(CURRENT DATE) * 10000 + MONTH(CURRENT DATE) * 100 + DAY(CURRENT DATE) 
AND WOHDR.divi = 'G'
AND NME.cuno NOT LIKE ('I%')
AND RPT.rplvl = ' ' 
AND WOHDR.cunm NOT IN ('ACCRUED VACATION TIME','ACCRUED VACATION','SICK TIME','SICK PAY')
AND WOHDR.acti IN ('O','C')
-- AND DATE(Cast(SUBSTRING(WOLBR.docdt8,1,4) as char(4)) ||'-'|| Cast(SUBSTRING(WOLBR.docdt8,5,2) as char(2)) ||'-'|| Cast(SUBSTRING(WOLBR.docdt8,7,2) as char(2))) = DATE(RTRIM(CHAR(WOHDR.llbjd8)))

GROUP BY
WOHDR.wono,EMP.eplsnm,WOLBR.cgcd,WOHDR.opndt8,WOHDR.divi,WOHDR.cunm, WOHDR.eqmfmd,WOSEG.wosgno,WOHDR.stno,WOHDR.prmdt8,RPT.ds5,WOHDR.acti

【问题讨论】:

总是最好地展示您的代码和您尝试过的内容。 特别是因为答案似乎假设一个简单的方向,但你最初的问题似乎是在其他地方...... 【参考方案1】:

您可以将其作为聚合查询:

SELECT WONO, EPLSNM, MAX(SQNO1)
FROM whatever w
GROUP BY WONO, EPLSNM;

编辑:

(基于评论中的澄清)

您可以使用窗口/分析函数:

select wono, eplsnm, sqn01
from (select w.*, row_number() over (partition by wono order by sqno1 desc) as seqnum
      from whatever w
     ) w
where seqnum = 1;

【讨论】:

戈登。感谢您的回复,我希望它像分组和获取 max(sqno1) 一样简单,但是在这样做之后,我仍然会为每个 WONO 获得多行。 WONO EPLSNM SQNO GW25261 CROSS, BRADLEY R 3 GW25261 DAVIS, DAVID L 2 我认为这是因为有 2 名不同的员工分配给 WONO GW25261,但我需要它做的只是为每个 WONO 显示一条线。在这种情况下,克罗斯应该出现,因为他的 SQNO 更高(3vs2)【参考方案2】:

破译您的数据有点困难,但您似乎只需要一个简单的分组依据?

SELECT WONO, EPLSNM, MAX(SQNO1)
FROM MYTABLE
GROUP BY WONO, EPLSNM

编辑:由于额外的说明。

SELECT WONO, EPLSNM, SQNO1
FROM MYTABLE mt
WHERE SQNO1 = (SELECT MAX(SQNO1) FROM MYTABLE WHERE WONO = mt.WONO)

【讨论】:

以上是关于DB2 和 SQL-如何在特定字段中返回最大值,以便每行只显示一条记录;从多个表中提取数据的主要内容,如果未能解决你的问题,请参考以下文章

db2 怎么在所有表查询某个字段的信息

确定应该在 DB2 中创建哪些索引以优化特定查询的性能

在SQL中,如何查询某一字段中最大值的数据

在SQL中,如何查询某一字段中最大值的数据

如何在 sql DB2 中使用条件其他字段和期间日期标记列?

数据库查询每个字段对应的最大值