如何在sql表中获取以前的所有者?

时间:2009-09-28 22:27:00

标签: sql ms-access

我有一个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),我需要查看他拥有的所有商品的列表以及最后一个所有者项目(他从哪个客户获得该项目)。

更多解释:

  • transId是主键和自动编号(身份) - 以前的所有者将比新主人拥有更小的transId
  • 交易中的customerId是买方(该交易后的新所有者)
  • 日期不包含时间;只有日期(不应该用于比较或订购,因为某些项目可以在一天内改变两个所有者)

这是一个让事情更清晰的例子(日期未显示):

        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|
        --------------------------------------------------

1 个答案:

答案 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;