加入后前1名不返回结果

时间:2019-06-04 18:42:45

标签: sql-server tsql

我有下面的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

enter image description here

但是,当我将其加入主查询时,其返回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'

enter image description here

我在这里想念东西吗?

4 个答案:

答案 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;