【问题标题】:SQL to find only those records which are before certain dateSQL仅查找特定日期之前的记录
【发布时间】:2018-06-27 09:24:26
【问题描述】:

我有上面的 2 个表和它们各自的列。

HEADER
    PO_Number (char)
    CUSTNMBR (char)
    Expiry_Date (datetime)
    PO_Status (tinyint, 0 = Open, 1 = Closed)
    STATUSDATE (datetime)

BATCH
    PORDNMBR (char)
    CUSTNMBR (char)
    BTCHID (char)
    DATE1 (datetime)

在 HEADER 表中,主键是 (PO_Number, CUSTNMBR)。 在 BATCH 表中,BTCHID 是主键。 DATE1 列是输入相应批次的日期。 此外,对于 HEADER 表中的每个 (PO_Number, CUSTNMBR) 组合,可能在不同日期输入多个 BTCHID。 我的截止日期是 2016-07-12,有截止日期之前的批次和截止日期之后的批次。

我需要识别那些在截止日期之后没有输入任何批次的 (PO_Number, CUSTNMBR) 组合,其中 Expiry_Date 表单 HEADER 是

我最初编写了以下查询,但结果是带来了截止日期之后也有批次的记录。我已经通过键入 PODNMBR 验证了使用 SELECT * from BATCH 查询,结果我可以看到截止日期之前和之后的批次。有什么方法可以识别那些在截止日期之后没有输入任何批次的那些,并且 Expiry_Date 表单 HEADER 是

SELECT BATCH.PORDNMBR, BATCH.CUSTNMBR, BATCH.BTCHID, BATCH.DATE1, 
HEADER.PO_Number, HEADER.CUSTNMBR, HEADER.Expiry_Date, HEADER.PO_Status, HEADER.STATUSDATE
FROM           BATCH
INNER JOIN
               HEADER
ON 
BATCH.CUSTNMBR = HEADER.CUSTNMBR 
AND 
BATCH.PORDNMBR = HEADER.PO_Number
WHERE BATCH.Expiry_Date < '2016-07-12 00:00:00'
AND BATCH.DATE1 < '2016-07-12 00:00:00'

【问题讨论】:

  • 添加一些示例表数据和预期结果。 (作为格式化文本,而不是图像。)考虑在您花费太多时间之前阅读stackoverflow.com/help/mcve
  • 顺便说一句,您使用的是哪个 dbms?在日期/时间方面,许多产品远不符合 ANSI SQL。
  • 我正在使用 SQL Server。

标签: sql sql-server tsql


【解决方案1】:

加入标识有效批次的子查询:

SELECT
    b1.PORDNMBR,
    b1.CUSTNMBR,
    b1.BTCHID,
    b1.DATE1, 
    h.PO_Number,
    h.CUSTNMBR,
    h.Expiry_Date,
    h.PO_Status,
    h.STATUSDATE
FROM BATCH b1
INNER JOIN
(
    SELECT PORDNMBR, CUSTNMBR
    FROM BATCH
    GROUP BY PORDNMBR, CUSTNMBR
    HAVING SUM(CASE WHEN Expiry_Date >= '2016-07-12 00:00:00' THEN 1 ELSE 0 END) = 0
) b2
    ON b1.PORDNMBR = b2.PORDNMBR AND
       b1.CUSTNMBR = b2.CUSTNMBR
INNER JOIN HEADER h
    ON b1.CUSTNMBR = h.CUSTNMBR AND 
       b1.PORDNMBR = h.PO_Number
WHERE
    b1.DATE1 < '2016-07-12 00:00:00';

您当前逻辑的问题是您正在对每条记录应用WHERE 子句中的到期日期逻辑。但是您确实希望将此逻辑应用于记录组。

【讨论】:

  • 抱歉迟到了,这行得通。你是对的,我之前错过了这个小组。感谢大家对大家的帮助。
【解决方案2】:

嗯。我在想你只想要标题信息,所以我想到了not exists

select h.*
from header h
where not exists (select 1
                  from batch b
                  where b.pordnmbr = h.prodnmbr and
                        b.custnmbr = h.custnmbr and
                        b.Expiry_Date < '2016-07-12' and
                        b.date1 > '2016-07-12'
                 );

日期算法与您的查询略有不同,符合您描述的逻辑。

【讨论】:

  • Expiry_Date 不在批次中
  • @Paparazzi 。 . .它在问题中:WHERE BATCH.Expiry_Date &lt; '2016-07-12 00:00:00'.
  • 它可能在选择中,但它不在表定义中。
【解决方案3】:

您的查询仅从批次中消除行 - 而不是整个批次

我认为这会奏效

declare @Expiry_Date datetime = '2016-07-12 00:00:00';

SELECT B.PORDNMBR, B.CUSTNMBR, B.BTCHID, B.DATE1, 
       H.PO_Number, H.CUSTNMBR, H.Expiry_Date, H.PO_Status, H.STATUSDATE
FROM   ( select * 
         from header 
         where Expiry_Date < @Expiry_Date
       ) H
JOIN BATCH B
  ON B.CUSTNMBR = H.CUSTNMBR 
 AND B.PORDNMBR = H.PO_Number
 AND NOT EXISTS ( SELECT 1 from batch 
                   WHERE BATCH.CUSTNMBR = H.CUSTNMBR 
                     AND BATCH.PORDNMBR = H.PO_Number 
                     AND BATCH.DATE1 >= @Expiry_Date 
                )
ORDER BY B.CUSTNMBR, B.PORDNMBR, B.BTCHID 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2019-09-18
    相关资源
    最近更新 更多