SQL比较2个日期并在> 3天时显示在表中

Posted

技术标签:

【中文标题】SQL比较2个日期并在> 3天时显示在表中【英文标题】:SQL Comparing 2 dates and displaying in table if >3 days 【发布时间】:2020-05-13 16:00:34 【问题描述】:

在我的表中,我有几个日期字段,当我运行查询时,我想将重新安排日期 (frsdt) 与截止日期 (frdte) 进行比较,并且只显示 > 3 天的记录。我拉了几天头发,以为我会寻求帮助。任何帮助将不胜感激。

SELECT fprod
    ,pord
    ,desc
    ,CASE 
    WHEN ftype = 'P' 
      THEN 'Planned' 
    ELSE 'Firm' 
    END
    ,vndnam
    ,fppvnd
    ,fqty
    ,DATE(TO_DATE(RTRIM(CHAR(fdate))
    ,DATE(TO_DATE(RTRIM(CHAR(frdte))
    ,DATE(TO_DATE(RTRIM(CHAR(frsdt))
    ,pecst * pqord
FROM avm
    ,kfp
    ,iiml01
    ,hpo 
INTO 
    :tblPAM.colItmNbr
    ,:tblPAM.colPONbr
    ,:tblPAM.colDesc
    ,:tblPAM.colType
    ,:tblPAM.colVendor
    ,:tblPAM.colVendorId
    ,:tblPAM.colQty
    ,:tblPAM.colRelDate
    ,:tblPAM.colDueDate
    ,:tblPAM.colRescDate
    ,:tblPAM.colPOAmount 
WHERE vendor = fppvnd 
    AND fprod = iprod 
    AND year(frsdt) < 9999 
    AND pldte > pddte + 3 days
    AND month(frsdt)|| '/' || day(frsdt) || '/' || year(frsdt) > month(frdte)|| '/' || day(frdte)  || '/' || year(frdte) 

建议从重写查询开始

SELECT T.*
FROM
(
SELECT fprod
    ,pord
    ,desc
    ,CASE 
    WHEN ftype = 'P' 
      THEN 'Planned' 
    ELSE 'Firm' 
    END some_alias1
    ,vndnam
    ,fppvnd
    ,fqty
    ,DATE(TO_DATE(RTRIM(CHAR(fdate)) fdate_alias
    ,DATE(TO_DATE(RTRIM(CHAR(frdte)) frdte_alias
    ,DATE(TO_DATE(RTRIM(CHAR(frsdt)) frsdt_alias
    ,pecst * pqord some_alias2
FROM avm
    ,kfp
    ,iiml01
    ,hpo 
WHERE vendor = fppvnd 
    AND fprod = iprod
) T 
WHERE year(frsdt_alias) < 9999 
  AND pldte_alias > pddte_alias + 3 days
  AND frsdt_alias > frdte_alias;

【问题讨论】:

您使用的是哪种格式的 SQL? 日期函数是非常产品特定的。请使用您正在使用的特定数据库标记您的问题。 Why should I “tag my RDBMS”? 我正在使用 Db2® for IBM® i 数据库。我是编程新手,所以我不确定你是否需要知道。对不起 试试date1 &gt; date2 + 3 daydate1 & date2 必须是 datetimestamp 数据类型。 @MarkBarinstein -- 我认为是+ 3 DAYS,如果您使用DAY 将不起作用 【参考方案1】:

下面是一个非常基本的示例,说明如何将数字日期表示形式转换为日期以及如何对日期进行基本数学运算。将此处的 MYTAB“虚拟”表视为包含 2 个数字列的表。 按原样运行。

SELECT *
FROM 
(
  SELECT
    DATE(TO_DATE(RTRIM(CHAR(D1)), 'YYYYMMDD')) DAT1
  , DATE(TO_DATE(RTRIM(CHAR(D2)), 'YYYYMMDD')) DAT2
  FROM
  (
  VALUES 
    (20181004, 20181007)
  , (20181004, 20181017)
  ) MYTAB (D1, D2)
) T
WHERE DAT2 > DAT1 + 3 DAY;

结果是:

|DAT1        |DAT2        |
|------------|------------|
|2018-10-04  |2018-10-17  |

【讨论】:

感谢马克的回复。让我看看这个。我非常感谢你们俩的帮助。 我很好奇马克。你的 where 语句中如何仍然没有将 D1 和 D2 读取为十进制数据类型? 我对带有DATE(TO_DATE(RTRIM(CHAR(Dx)), 'YYYYMMDD')) 表达式的列使用了相同的别名Dx。这些列之后具有DATE 数据类型。为了便于理解,我更新了示例。 我以这种形式提供示例的原因是,它可以按原样运行。想象一下,您有一个表MYTAB,其中包含 2 个数字列 D1 和 D2。在这种情况下,FROM (VALUES ...) MYTAB (D1, D2) 子句将更改为 FROM MYTAB。我在这里所做的是首先使用子选择(它们的别名是 DAT1 和 DAT2)形成一个包含 2 个日期列的“临时”结果集,其中每一列都是表达式的结果。使用这样一个临时结果集很方便,因为我不必再重复多次使用相同的长表达式。 因此,一旦将数据类型从十进制转换为日期,它是否还记得在阅读其余查询时?【参考方案2】:

你可以使用日期算术来解决这个问题。

例如在 SQL Server 中它看起来像这样:

WHERE dateadd(day,3, frsdt) >= frdte

在 DB2 中它看起来像这样

WHERE frsdt + 3 DAYS >= frdte

在这里,我将第一个日期加上 3 天。如果它大于目标日期,那么我知道它们相隔不到 3 天。

如果我想知道日期是否相隔超过 3 天,我会改为这样做

WHERE dateadd(day,3, frsdt) < frdte

添加日期的功能会根据您使用的平台而有所不同——但基本思想遵循我上面展示的内容。将日期加上 3 天,然后在 WHERE 语句中进行比较。

【讨论】:

霍根感谢您的回复。我已经尝试过了,我总是收到以下错误。 DB2/400 SQL:-206[IBM][System i Access ODBC 驱动程序][DB2 for i5/OS]SQL0206 - 未找到列或全局变量 DAY。 任何人都知道我为什么会收到这个错误。未找到列或全局变量 DAY @MikeOffenbecher 您没有显示给出错误的 db2 代码,但我在上面举了一个示例——如果您仍然收到错误,请告诉我您的代码是什么。 所以当我使用“WHERE frsdt + 3 DAYS >= frdte”时,我得到使用标记的持续时间无效。我确信它是因为数据库中的列是十进制而不是日期。如您所见,我在查询中将它们转换为日期(可以这么说)。该表是很久以前建立的,我正在尝试使用我所拥有的,因为其中有很多数据。 我在上面的原始帖子中发布了更新的代码。

以上是关于SQL比较2个日期并在> 3天时显示在表中的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 在 SQL 中的日期之间搜索?

具有 Power Query 日期的动态 SQL 查询

access中的日期比较

为每年 SQL 选择相同的日期

jooq 比较 2 个日期 - 它不喜欢 java.sql.Date

SQL 时间比较