查询每个产品和零件类型的最新记录日期(包括零件类型为空)
Posted
技术标签:
【中文标题】查询每个产品和零件类型的最新记录日期(包括零件类型为空)【英文标题】:Query for latest record date for each product and part type (Include part type is null) 【发布时间】:2021-05-14 09:08:21 【问题描述】:我的数据库是这样的 表名:Process_Result
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Product_No '' Part_Type '' INPUT_DATE '' PROCESS_CD ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' 111111 '' '' 01/05/2021 '' First ''
'' 111111 '' M '' 10/05/2021 '' Five ''
'' 111111 '' M '' 01/05/2021 '' Four ''
'' 111111 '' N '' 03/05/2021 '' First ''
'' 222222 '' '' 02/05/2021 '' Second ''
'' 222222 '' '' 05/05/2021 '' Third ''
'' 222222 '' N '' 10/05/2021 '' First ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
同时选择产品和零件类型并仅选择最大日期行
我想要的结果:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Product_No '' Part_Type '' INPUT_DATE '' PROCESS_CD ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' 111111 '' '' 01/05/2021 '' First ''
'' 111111 '' M '' 10/05/2021 '' Five ''
'' 111111 '' N '' 03/05/2021 '' First ''
'' 222222 '' '' 05/05/2021 '' Third ''
'' 222222 '' N '' 10/05/2021 '' First ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
现在我的查询如下所示:
SELECT product_no,
part_type,
input_time,
process_cd
FROM process_result AS A
WHERE A.input_time = (SELECT Max(input_time)
FROM process_result AS B
WHERE A.product_no = B.product_no
AND A.part_type = B.part_type)
不显示A表的空数据等于B表的空数据 我已经在google上搜索了,我仍然不明白。 现在结果是这样的:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Product_No '' Part_Type '' INPUT_DATE '' PROCESS_CD ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' 111111 '' M '' 10/05/2021 '' Five ''
'' 111111 '' N '' 03/05/2021 '' First ''
'' 222222 '' N '' 10/05/2021 '' First ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
【问题讨论】:
你有表格和插入语句的脚本吗? 只有sql问题兄弟抱歉。 【参考方案1】:Product_No 和 Part_Type 在这里看起来很自然,尝试使用 row_number()...
select Product_No, Part_Type, Input_Date, Process_CD
from (
select Product_No, Part_Type, Input_Date, Process_CD,
rn = row_number() over (partition by product_no, part_type order by Input_Date desc)
from dbo.Process_Result
) src
where rn=1;
【讨论】:
【参考方案2】:NULL
在 sql 中表示“未定义”或“未知”。什么都不等于未知值,结果也是未知的。因此,连接中的 NULL
值将不匹配。但是您可以将NULL
替换为带有COALESCE
的空字符串:
SELECT product_no,
part_type,
INPUT_DATE AS input_time,
process_cd
FROM process_result AS A
WHERE A.INPUT_DATE = (SELECT Max(INPUT_DATE)
FROM process_result AS B
WHERE A.product_no = B.product_no
AND COALESCE(A.part_type,'') = COALESCE(B.part_type,''))
这是一个 sql-fiddle 演示:http://sqlfiddle.com/#!18/75bf07/5
但我也更喜欢 sql-server 中的ROW_NUMBER
approach。
(请注意,您在数据中使用了INPUT_DATE
,但在您的sql 中使用了input_time
)
【讨论】:
我的数据库是 DB2。我认为它没有 COALESCE。你有别的办法吗? @ThanakornThongsomboon:afaik 所有数据库都知道COALESCE
。另外,如果是 DB2,为什么要标记 Microsoft rdbms 的 SQL-Server?
@ThanakornThongsomboon,如果您使用的是 DB2,请使用 DB2 标记您的问题并删除 Microsoft SQL Server 标记 (sql-server)。也就是说,我希望 DB2 将支持标准 SQL COALESCE
函数。
@DanGuzman 对不起兄弟。这是我的第一篇文章,我不知道。谢谢你的建议。
这太棒了兄弟。非常感谢。【参考方案3】:
这很简单:几乎所有NULL
值之间的比较都会返回NULL
。 WHERE
子句保留条件评估为 TRUE
的行,因此过滤掉 NULL
值。
SQL 标准支持NULL
-安全比较,因此NULL IS NOT DISTINCT FROM NULL
返回TRUE
。但是,NULL = NULL
返回NULL
。您可以使用 IS DISTINCT FROM
谓词编写此代码:
SELECT pr.product_no, pr.part_type, pr.input_time, pr.process_cd
FROM process_result pr
WHERE pr.input_time = (SELECT MAX(pr2.input_time)
FROM process_result pr2
WHERE pr2.product_no = pr.product_no AND
pr2.part_type IS NOT DISTINCT FROM pr.part_type
);
或者没有:
SELECT pr.product_no, pr.part_type, pr.input_time, pr.process_cd
FROM process_result pr
WHERE pr.input_time = (SELECT MAX(pr2.input_time)
FROM process_result pr2
WHERE pr2.product_no = pr.product_no AND
(pr2.part_type = pr.part_type OR pr2.part_type IS NULL and pr.part_type IS NULL)
);
请注意,这使用了 显式 比较。它不会将NULL
替换为另一个值——这可能会与另一行中的现有值混淆。
也就是说,AlwaysLearning 使用ROW_NUMBER()
的方法可能是一种更好的方式来制定您的查询。
【讨论】:
Db2 确实支持DISTINCT predicate。 @MarkBarinstein 。 . .谢谢你。我以为我在写它不支持之前确实检查过。 . .我可能正在寻找 NULL 安全的相等性。以上是关于查询每个产品和零件类型的最新记录日期(包括零件类型为空)的主要内容,如果未能解决你的问题,请参考以下文章