#sql #sql-server
#sql #sql-сервер
Вопрос:
Существует большая таблица транзакций. Я скопировал все транзакции для определенного элемента в другую таблицу (называемую TransactionsTest) с точно такими же столбцами для тестирования.
Таблица Transactions выглядит следующим образом:
---------------- -------------- --------------------- ------------- ----------------------
| Transaction_ID | Inventory_ID | Transaction_DT | Location_ID | Transaction_Quantity |
---------------- -------------- --------------------- ------------- ----------------------
| 39993 | 302 | 2017-01-26 12:41:00 | 1 | 2 |
| 39964 | 112 | 2017-01-26 9:55:00 | 20 | 1 |
| 39890 | 417 | 2017-01-20 9:54:00 | 3 | 5 |
| 39794 | 302 | 2017-01-11 9:50:00 | 3 | 3 |
| 39790 | 302 | 2017-01-10 10:45:00 | 20 | 2 |
| 39681 | 225 | 2017-01-02 8:32:00 | 20 | 4 |
| 39682 | 227 | 2017-01-02 8:15:00 | 1 | 1 |
| 39679 | 302 | 2017-01-01 11:23:00 | 3 | 6 |
| 39599 | 302 | 2016-12-11 10:21:00 | 1 | 2 |
---------------- -------------- --------------------- ------------- ----------------------
Таким образом, таблица TransactionsTest, содержащая только транзакции для определенного элемента, выглядит следующим образом:
---------------- -------------- --------------------- ------------- ----------------------
| Transaction_ID | Inventory_ID | Transaction_DT | Location_ID | Transaction_Quantity |
---------------- -------------- --------------------- ------------- ----------------------
| 39993 | 302 | 2017-01-26 12:41:00 | 1 | 2 |
| 39794 | 302 | 2017-01-11 9:50:00 | 3 | 3 |
| 39790 | 302 | 2017-01-10 10:45:00 | 20 | 2 |
| 39679 | 302 | 2017-01-01 11:23:00 | 3 | 6 |
| 39599 | 302 | 2016-12-11 10:21:00 | 1 | 2 |
---------------- -------------- --------------------- ------------- ----------------------
Я создал 2 разных запроса, чтобы возвращать только самую последнюю транзакцию в каждое местоположение. Вот первый:
SELECT t1.*
FROM TransactionsTest t1
WHERE t1.Transaction_DT = (SELECT MAX(t2.Transaction_DT)
FROM TransactionsTest t2
WHERE t2.Location_ID = t1.Location_ID)
AND Inventory_ID = 302 ORDER BY t1.Transaction_DT
И вот второй:
SELECT t1.*
FROM TransactionsTest t1
WHERE t1.Transaction_ID = (SELECT TOP 1 t2.Transaction_ID
FROM TransactionsTest t2
WHERE t2.Location_ID = t1.Location_ID
ORDER BY t2.Transaction_ID DESC)
AND Inventory_ID = 302 ORDER BY t1.Transaction_DT
Оба запроса возвращают этот результат при запросе TransactionsTest:
---------------- -------------- --------------------- ------------- ----------------------
| Transaction_ID | Inventory_ID | Transaction_DT | Location_ID | Transaction_Quantity |
---------------- -------------- --------------------- ------------- ----------------------
| 39993 | 302 | 2017-01-26 12:41:00 | 1 | 2 |
| 39794 | 302 | 2017-01-11 9:50:00 | 3 | 3 |
| 39790 | 302 | 2017-01-10 10:45:00 | 20 | 2 |
---------------- -------------- --------------------- ------------- ----------------------
Но когда я запускаю те же запросы к фактической таблице транзакций, вот так:
SELECT t1.*
FROM Transactions t1
WHERE t1.Transaction_DT = (SELECT MAX(t2.Transaction_DT)
FROM Transactions t2
WHERE t2.Location_ID = t1.Location_ID)
AND Inventory_ID = 302 ORDER BY t1.Transaction_DT
Или это:
SELECT t1.*
FROM Transactions t1
WHERE t1.Transaction_ID = (SELECT TOP 1 t2.Transaction_ID
FROM Transactions t2
WHERE t2.Location_ID = t1.Location_ID
ORDER BY t2.Transaction_ID DESC)
AND Inventory_ID = 302 ORDER BY t1.Transaction_DT
Результирующий набор пуст, вот так:
---------------- -------------- ---------------- ------------- ----------------------
| Transaction_ID | Inventory_ID | Transaction_DT | Location_ID | Transaction_Quantity |
---------------- -------------- ---------------- ------------- ----------------------
| | | | | |
---------------- -------------- ---------------- ------------- ----------------------
Кто-нибудь может сказать, что здесь происходит? Почему запросы возвращают ожидаемый результат только для таблицы с транзакциями для определенного элемента? Единственное, о чем я могу думать, это то, что это может иметь какое-то отношение к тому, как была создана исходная таблица транзакций, потому что я не дублировал все ограничения / внешние ключи и т.д.
Комментарии:
1. SQL Server <> MySQL. Что вы на самом деле используете?
Ответ №1:
Условие инвентаризации также должно быть в подзапросе:
WHERE t1.Transaction_ID = (SELECT TOP 1 t2.Transaction_ID
FROM TransactionsTest t2
WHERE t2.Location_ID = t1.Location_ID AND
t2.Inventory_ID = t.Inventory_ID
ORDER BY t2.Transaction_ID DESC
)
В противном случае самая последняя транзакция может иметь другое значение для Inventory_ID
.
Комментарии:
1. Это сработало! Добавление И t2.Inventory_ID = t1.Inventory_ID к обоим запросам вернуло ожидаемый результат из полной таблицы транзакций.