我有上面的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是<截止日期。
我最初编写了以下查询,但结果是带来了截止日期后也有批次的记录。我已经通过键入PORDNMBR验证了从BATCH查询中使用SELECT *,结果我可以在截止日期之前和截止日期之后看到批次。是否有任何方法可以识别那些在截止日期之后没有输入任何批次的那些并且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'
答案 0 :(得分:0)
加入一个标识有效批次的子查询:
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
子句中对每条记录应用到期日期逻辑。但是你真的想把这个逻辑应用于记录组。
答案 1 :(得分:0)
嗯。我想你只是想要标题信息,所以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'
);
日期算术与您的查询略有不同,与您描述的逻辑相匹配。
答案 2 :(得分:0)
您的查询只会删除批次中的行 - 而不是整个批次
我认为这会起作用
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