Топ 1 не возвращает результаты, когда присоединился - PullRequest
1 голос
/ 04 июня 2019

У меня ниже 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

Однако, когда явключите это в мой основной запрос, возвращающий нуль.

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 ]

2 голосов
/ 04 июня 2019

Можете ли вы проверить этот следующий запрос-

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 голос
/ 04 июня 2019

Причина, по которой исходный запрос не работает, связана с порядком операций.

Производная таблица T2 дала 1 и только 1 запись; не 1 запись на номер ЧАСТИ. Это связано с тем, что производная таблица получает результаты до того, как ее можно будет соединить с T1. Так как номера деталей не совпадают, если вам не повезет с частью и днем ​​и компанией ... вы не получите никаких данных. Перекрестное / внешнее применение позволяет получить ТОП-запись по критериям присоединения. и, таким образом, вернет несколько записей; 1 для каждой части и компании; вместо 1.

Я думаю, что вы после перекрестного или внешнего применения, и вы можете избежать 2-го фильтра в производной таблице (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 и разделение вашей компании и partNum при сортировке по transdate и возвращать только номер строки, 1-й по порядку при трансдате по убыванию.

Вот ссылка MSDN Doc , показывающая, как применяется перекрестный / внешний работы.

0 голосов
/ 04 июня 2019

Я бы предложил более простой запрос:

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;
0 голосов
/ 04 июня 2019

Попробуйте удалить 'LEFT' в вашем объединении, потому что оно позволяет вам выбирать строки в подзапросе, которые не соответствуют критериям вашего предложения WHERE. Похоже, это решило проблему в моей текстовой среде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...