请考虑我的表格(这只是一个简化版本,在我的项目中,我有600,000条记录):
Id TransactionId TransactionTypeId Description
1 1 1 Description1
2 1 1 Description2
3 1 2 Description3
4 1 2 Description4
5 1 1 Description5
6 1 2 Description6
7 2 1 Description7
8 2 1 Description8
9 2 2 Description9
10 2 2 Description10
我需要做的是当TransactionTypeId = 1
时,我需要从该表中获取最新数据。否则,当TransactionTypeId <> 1
时,我需要全部获取它们。
对于这个例子,我有这个查询:
SELECT MAX(T.Id)
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionId ORDER BY T.Id DESC), ',', 1) AS TransactionId
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionTypeId ORDER BY T.Id DESC), ',', 1) AS TransactionTypeId
, SUBSTRING_INDEX(GROUP_CONCAT(T.Description ORDER BY T.Id DESC), ',', 1) AS Description
FROM Transactions T
GROUP BY T.TransactionId
, CASE WHEN T.TransactionTypeId = 1 THEN T.TransactionTypeId END
ORDER BY T.TransactionId, T.TransactionTypeId
我希望的结果是:
Id TransactionId TransactionTypeId Description
5 1 1 Description5
3 1 2 Description3
4 1 2 Description4
6 1 2 Description6
8 2 1 Description8
9 2 2 Description9
10 2 2 Description10
但我的问题是,即使TransactionTypeId <> 1
,查询仍然将它们分组。
我的查询返回:
Id TransactionId TransactionTypeId Description
5 1 1 Description5
6 1 2 Description6
8 2 1 Description8
10 2 2 Description10
我知道我可以在这里使用UNION
来分隔TransactionTypeId
列的查询,但我不能,我花了5分多钟才得到结果。有没有可能(如果没有,我别无选择,只能使用UNION
)方式来解决这个问题?
谢谢:)
更新#1
当我使用UNION
时,这是我的查询。
SELECT Transaction.Id
, Transaction.TransactionId
, Transaction.TransactionTypeId
, Transaction.Description
FROM (
SELECT MAX(T.Id)
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionId ORDER BY T.Id DESC), ',', 1) AS TransactionId
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionTypeId ORDER BY T.Id DESC), ',', 1) AS TransactionTypeId
, SUBSTRING_INDEX(GROUP_CONCAT(T.Description ORDER BY T.Id DESC), ',', 1) AS Description
FROM Transactions T
WHERE T.TransactionTypeId = 1
GROUP BY T.TransactionId
UNION
SELECT T.Id
, T.TransactionId
, T.TransactionTypeId
, T.Description
FROM Transactions T
WHERE T.TransactionTypeId <> 1
) Transaction
ORDER BY Transaction.TransactionId, Transaction.TransactionTypeId
答案 0 :(得分:5)
尝试这个
SELECT MAX(T.Id)
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionId ORDER BY T.Id DESC), ',', 1) AS TransactionId
, SUBSTRING_INDEX(GROUP_CONCAT(T.TransactionTypeId ORDER BY T.Id DESC), ',', 1) AS TransactionTypeId
, SUBSTRING_INDEX(GROUP_CONCAT(T.Description ORDER BY T.Id DESC), ',', 1) AS Description
FROM Transactions T
GROUP BY CASE WHEN T.TransactionTypeId = 1 THEN CONCAT(T.TransactionId,'-',T.TransactionTypeId) ELSE T.Id END
ORDER BY T.TransactionId, T.TransactionTypeId
答案 1 :(得分:0)
试试这个。我看到的唯一减速因素是最终排序 - 所以你可以先试用它而不用ORDER BY
:
SELECT T.Id
, T.TransactionId
, 1 AS TransactionTypeId
, T.Description
FROM Transactions T
JOIN
( SELECT MAX(Id) AS Id
FROM Transactions
WHERE TransactionTypeId = 1
GROUP BY TransactionId
) AS grp
ON grp.Id = T.Id
UNION ALL
SELECT T.Id
, T.TransactionId
, T.TransactionTypeId
, T.Description
FROM Transactions T
WHERE T.TransactionTypeId <> 1
ORDER BY TransactionId, TransactionTypeId
你也可以使用它(非UNION
但有OR
所以我无法确定性能)查询:
SELECT T.Id
, T.TransactionId
, T.TransactionTypeId
, T.Description
FROM Transactions T
WHERE T.TransactionTypeId <> 1
OR NOT EXISTS
( SELECT *
FROM Transactions tm
WHERE tm.TransactionTypeId = 1
AND tm.TransactionId = T.TransactionId
AND tm.Id > T.Id
)
ORDER BY T.TransactionId, T.TransactionTypeId