我有下面的SQL查询,该查询试图返回特定零件的最后交易日期。当我自行运行子查询(使用特定于零件的条件)时,剩下的子查询运行良好
SELECT TOP 1 S1.*
FROM PartTran S1
WHERE S1.TranDate > '10/10/2016' AND S1.TranType <> 'ADJ-CST' AND S1.PartNum = '0000AAAO' ORDER BY S1.TranDate DESC
但是,当我将其加入主查询时,其返回null。
SELECT T1.PartNum, T2.TranDate, T2.TranType
FROM dbo.Part T1
LEFT JOIN (SELECT TOP 1 S1.* FROM PartTran S1 WHERE S1.TranDate > '10/10/2016' AND S1.TranType <> 'ADJ-CST' ORDER BY S1.TranDate DESC) T2 ON T1.Company = T2.Company AND T1.PartNum = T2.PartNum
WHERE T1.PartNum = '0000AAAO'
我在这里想念东西吗?
答案 0 :(得分:2)
能否请您检查以下查询-
SELECT
T1.PartNum,
T2.TranDate,
T2.TranType
FROM dbo.Part T1
LEFT JOIN
(
SELECT TOP 1 S1.*
FROM PartTran S1
WHERE S1.TranDate > '10/10/2016'
AND S1.TranType <> 'ADJ-CST'
AND S1.PartNum = '0000AAAO'
-- I think this above filter (AND S1.PartNum = '0000AAAO') is required
-- other wise top 1 can select records belongs to other PartNum and
-- your left join will return NULL logically
ORDER BY S1.TranDate DESC
) T2 ON T1.Company = T2.Company
AND T1.PartNum = T2.PartNum
WHERE T1.PartNum = '0000AAAO';
答案 1 :(得分:1)
原始查询无法正常运行的原因与操作顺序有关。
派生表T2产生1条记录,只有1条记录;每个部件号没有1条记录。这与派生表在可以连接到T1之前获取其结果有关。由于零件编号不匹配,除非您对零件,日期和公司感到幸运...您将不会获得任何数据。交叉/外部申请允许您根据“加入条件”获得TOP记录。因此将返回多个记录;每个零件和公司1个;而不只是1。
我认为您是在进行交叉申请或外部申请之后,可以避免在派生表(T2)中使用第二个过滤器。如果您希望不保留任何交易的部分,请使用外部申请,如果您只希望具有部分交易使用交叉申请。
SELECT T1.PartNum, T2.TranDate, T2.TranType
FROM dbo.Part T1
CROSS APPLY (SELECT TOP 1 S1.*
FROM PartTran S1
WHERE S1.TranDate > '10/10/2016'
AND S1.TranType <> 'ADJ-CST'
ORDER BY S1.TranDate DESC) T2
ON T1.Company = T2.Company
AND T1.PartNum = T2.PartNum
WHERE T1.PartNum = '0000AAAO'
或者,您可以使用行号来代替公司的top和partition,也可以使用partNum来按日期排序,而仅返回行号1来按日期降序排序。
这里有一个MSDN Doc链接,显示了交叉/外部应用方式 有效。
答案 2 :(得分:0)
请尝试删除联接中的“ LEFT”,因为它允许您在子查询中选择不符合WHERE子句条件的行。这似乎至少可以解决我的文本环境中的问题。
答案 3 :(得分:0)
我建议一个更简单的查询:
SELECT TOP 1 p.PartNum, T.TranDate, T.TranType
FROM dbo.Part p JOIN
PartTran pt
ON pt.Company = p.Company AND
pt.PartNum = t.PartNum AND
pt.TranType <> 'ADJ-CST' AND
pt.TranDate > '2016-10-10'
WHERE p.PartNum = '0000AAAO'
ORDER BY pt.TranDate DESC;