查询每个产品和零件类型的最新记录日期(包括零件类型为空)

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 值之间的比较都会返回NULLWHERE 子句保留条件评估为 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 安全的相等性

以上是关于查询每个产品和零件类型的最新记录日期(包括零件类型为空)的主要内容,如果未能解决你的问题,请参考以下文章

不同维度类型的相同事实

在 Oracle SQL 查询中选择最新的

查询使用了全部零件的工程名称

如何构建具有多种项目类型的模式(服务,零件和保险等)

使用SQL语言,求每个工程项目使用供应零件的总数量。

论文研究 | 基于 MPL 分类器的零件识别