我有一个Transaction表(transId,sn,customerId,date),列出了客户之间的项目交易。有些商品有sn(序列号),从一个顾客到另一个顾客。对于某些客户(12345678),我需要找出谁是客户项目的最后一位所有者。
这是我的疑问:
SELECT c.*,
p.transId,
p.customerId
FROM Transaction c
LEFT JOIN Transaction p ON c.sn = p.sn
WHERE p.transId = (SELECT MAX(t.transId)
FROM Transaction t
WHERE t.transId < c.transId
AND t.sn = c.sn)
AND c.customerId = 12345678
ORDER BY p.transId;
此查询正常工作,除非项目没有以前的所有者。应为p.transId和p.customerId返回null,但是insead返回0行。数据库访问。
更新:我需要 BOTH 当前所有者和结果中的前任所有者(在一行中)。并且,它应该适用于中间所有者(如日志;如果客户不是当前所有者,但之前是所有者)。
更新:对于某个客户(将作为参数传递;在我们的例子中为customerId = 12345678),我需要查看他拥有的所有商品的列表以及最后一个所有者项目(他从哪个客户获得该项目)。
更多解释:
这是一个让事情更清晰的例子(日期未显示):
transaction table ----------------------- |transId|sn|customerId| | 1| 1| 12345678| | 2| 2| 87654321| | 3| 2| 12345678| | 4| 2| 11223344| | 5| 2| 12345678| ----------------------- for customerId=12345678 result should be result -------------------------------------------------- |transId|sn|customerId|prevTransId|prevCustomerId| | 1| 1| 12345678| NULL| NULL| | 3| 2| 12345678| 2| 87654321| | 5| 2| 12345678| 4| 11223344| --------------------------------------------------
答案 0 :(得分:0)
将p.transId = ...
的条件从WHERE子句移动到JOIN条件(在任何情况下都不需要c.sn = p.sn
):
普通SQL:
SELECT c.*,
p.transId,
p.customerId
FROM Transaction c
LEFT JOIN Transaction p
ON p.transId = (SELECT MAX(t.transId)
FROM Transaction t
WHERE t.transId < c.transId
AND t.sn = c.sn)
WHERE c.customerId = 12345678
ORDER BY p.transId;
MS Access SQL:
SELECT c.*,
p.transId,
p.customerId
FROM Transaction c
LEFT JOIN ((SELECT t.transId, MAX(z.transId) AS PrevTransId
FROM Transaction t
LEFT JOIN Transaction z on t.sn = z.sn
WHERE z.transId < t.transId
GROUP BY t.transId) x
LEFT JOIN Transaction p ON p.TransId = x.PrevTransId
) ON x.TransId = c.TransId
WHERE c.customerId = 12345678
ORDER BY p.transId;