检索每个ID的最新记录。如何在SQL中?

时间:2014-02-26 20:10:56

标签: mysql sql database ms-access greatest-n-per-group

我有两张桌子。一个表存储有关ID和描述等库存项目的基本信息。另一个表存储每天结束时库存物品的状态;因此,此表中有许多行具有相同的inventoryItemID但不同的日期。下面基本上是我的表格。

TABLE: listItems
|itemRecordNumber|itemName|minStock|reorderQty|note|
|      510       |  bag   |   10   |    20    |    |
|      511       |  ball  |   20   |    40    |    |
|      512       |  shoe  |   09   |    10    | xx |

TABLE: inventoryTrans
|itemRecordNumber|recordType|quantity| trans_date |
|      510       |    50    |   30   | 09/12/2013 |
|      510       |    40    |   33   | 09/12/2013 |
|      510       |    50    |   35   | 08/12/2013 |
|      510       |    40    |   35   | 08/12/2013 |
|      511       |    50    |   10   | 08/12/2013 |
|      511       |    40    |   15   | 09/12/2013 |
|      512       |    50    |   33   | 07/12/2013 |
|      512       |    40    |   34   | 09/12/2013 |

现在,我想要的是,每个itemRecordNumber的表inventoryTrans中的最新记录,只有类型50(销售)的记录,但等待更多,如果项目中listItems中的注释是' xx'我对这个结果不感兴趣。我真正需要的是数量。请注意,此表没有项目名称/ minStock / reorderQty,这就是为什么我需要第一个表listItems来获取该信息。

所以在我希望得到的单个查询中,

|itemRecordNumber|itemName| trans_date |quantity|minStock|reorderQty|
|      510       |  bag   | 09/12/2013 |   30   |   10   |    20    |
|      511       |  ball  | 08/12/2013 |   10   |   20   |    40    |

所以我想要的是这些信息。请注意,对于每个ID,它是recordType“50”的最新版本,但由于项目中的注释为listItems.note中的“xx”,因此排除了项目512;

现在,在你批评表格的构造之前,我不能改变它。这就是Peachtree会计(我手边的软件正在使用的软件)的表格是如何布局的,所以这就是我必须要处理的。目标是生成有关库存的自定义信息,以便更好地进行管理。

现在我该如何为此构建SQL查询。我见过人们在其他一些类似的例子中使用LEFT JOIN,但是我无法让它工作。

2 个答案:

答案 0 :(得分:1)

我们走了

http://sqlfiddle.com/#!2/d30823/1这是您的数据示例

SELECT a.itemRecordNumber,
       a.itemName,
       max(b.trans_date) AS trans_date,
       b.quantity,
       a.minStock,
       a.reorderQty
FROM listItems a,
     inventoryTrans b
WHERE a.itemRecordNumber = b.itemRecordNumber
  AND a.note<>'xx'
  AND b.recordtype=50
GROUP BY a.itemRecordNumber

编辑: 在MS Access(我无法测试)的情况下,这应该工作,你可以尝试(我尝试了MS SQL,这是我可以在SQLFiddle中测试的最接近的

http://sqlfiddle.com/#!3/d30823/2

SELECT a.itemRecordNumber,
       a.itemName,
       max(b.trans_date) AS trans_date,
       b.quantity,
       a.minStock,
       a.reorderQty
FROM listItems a,
     inventoryTrans b
WHERE a.itemRecordNumber = b.itemRecordNumber
  AND a.note<>'xx'
  AND b.recordtype=50
  AND b.trans_date =
    (SELECT max(trans_date)
     FROM inventoryTrans c
     WHERE c.itemRecordNumber = b.itemRecordNumber
       AND c.recordtype=50)
GROUP BY a.itemRecordNumber,
         a.itemName,
         b.quantity,
         a.minStock,
         a.reorderQty

让我知道,如果它因任何原因不适合你,我得到与你的问题相同的结果

答案 1 :(得分:0)

虽然这不是最有效的方法,但它应该有用。

SELECT l.*, i.trans_date, i.quantity
FROM listItems as l
    JOIN (SELECT i.itemRecordNumber, MAX(trans_date) as date
          FROM inventoryTrans as i GROUP BY i.itemRecordNumber
     ) as x ON x.itemRecordNumber = l.itemRecordNumber
    JOIN inventoryTrans as i ON l.itemRecordNumber = i.itemRecordNumber
        AND i.trans_date = x.date
WHERE i.recordType = 50

虽然这也会为itemRecordNumber = 512添加一行,但如果您不需要,可以添加WHERE并根据需要进行过滤。