Левое соединение возвращает дополнительные данные, которые я хочу исключить

#sql #sql-server

Вопрос:

У меня есть 2 таблицы, как показано ниже :

 Employee: 

EmployeeId
EmployeeName
DeptId

Transactions:

TRID   
EmployeeId
Status(Pending,Done,InProgress,Rejected)
 

Теперь я хочу, чтобы все сотрудники из EmployeeTable for DeptId = 100 . Я хочу рассчитать Pending статус для тех сотрудников, чьи транзакции являются pending .

Поэтому, если записи сотрудников найдены в таблице Транзакций, то просто нужно вернуть столбец, в котором указано, есть ли у сотрудника какие-либо незавершенные транзакции или нет)

Запрос:

 SELECT
        e.*,
        CASE WHEN (t.EmployeeId is not null and t.Status!= 'Done')
            THEN CAST(1 AS BIT) 
            ELSE CAST(0 AS BIT) 
        End as IsPendingTransaction,
    FROM 
        Employee e
        left join Transactions t on e.EmployeeId = t.EmployeeId
    where e.DeptId = 100
 

Теперь проблема в том, что есть сотрудники, у которых в таблице транзакций несколько транзакций, но для этих сотрудников я просто хочу рассмотреть их последнюю транзакцию и
рассчитать статус IsPendingTransaction на основе этого. В основном order by Descending on TRID при расчете статуса IsPendingTransaction для сотрудников из таблицы транзакций.
Если у сотрудников нет никаких транзакций, то IsPendingTransaction будет «Ложным».

Кто-нибудь может, пожалуйста, помочь мне с этим?

Комментарии:

1. SQL Server не поддерживает одинарные кавычки для разделителей строк, поэтому ваш код вызывает подозрения.

2. Возможно, однажды вас ждет грубое пробуждение, когда кто-то отменит транзакцию или исправит старую транзакцию способом, который вы не учитываете. Будьте осторожны с определением «последние».

Ответ №1:

Воспользуйся outer apply :

 SELECT e.*,
       (CASE WHEN (t.EmployeeId is not null and t.Status <> 'Done')
             THEN CAST(1 AS BIT) 
             ELSE CAST(0 AS BIT) 
        End) as IsPendingTransaction
FROM Employee e OUTER APPLY
     (SELECT TOP (1) t.*
      FROM Transactions t 
      WHERE e.EmployeeId = t.EmployeeId
      ORDER BY t.trID DESC
     ) t
WHERE e.DeptId = 100;
 

Комментарии:

1. Приветствую вас за ваши добрые усилия по оказанию мне помощи. Нужно ли нам это условие «t.EmployeeID не равен нулю» в IsPendingTransaction?

2. @ILoveStackoverflow . . . Нет. Первые NULL значения не совпадут. Во-вторых, я был бы удивлен, если бы это когда-нибудь было NULL в Transactions таблице.

3. На самом деле, возможно, что не все сотрудники в таблице сотрудников будут иметь транзакции, и, поскольку я использовал левое соединение, именно поэтому я добавил условие проверки null. С вашей версией, какова была бы правильная логика для расчета IsPendingTransaction?

4. @ILoveStackoverflow . . . NULL Проверка CASE все еще там.

5. ОК. Я также включу проверку на ноль в свой окончательный запрос. Большое вам спасибо за быструю помощь и приятную внешнюю логику применения. Помогло мне узнать что-то новое 🙂