SQL JOIN + GROUP BY从MAX行选择数据(日期)

时间:2011-12-23 15:54:12

标签: sql sql-server join group-by

我在查找此SQL查询的解决方案时遇到了问题。

模式

修改:添加项目表

项目表

  • PK ItemID
  • 很多其他专栏

关联表

  • FK ItemID uniqueidentifier
  • FK TransactionID uniqueidentifier

交易表

  • PK ID uniqueidentifier
  • EntryDateTime DateTime
  • (其他几行int,varchar ......)

编辑:我认为我没有明确表达关系。每个ITEM(表未显示)可以有多个事务。多个项目可以共享相同的事务(因此链接表)。

请查看我当前查询的底部。我已经离开了这个问题以显示问题的进展。

<击> 我想做这样的查询。技巧是我希望t.varchar和t.int列是MAX(t.EntryDateTime)行中的任何值。我甚至不知道group by是否是进行此查询的正确方法。

SELECT lt.ItemID, MAX(t.EntryDateTime), t.varchar, t.int 
FROM LinkingTable lt
LEFT JOIN Transactions t ON lt.TransactionID = t.ID
GROUP BY lt.ItemID 

<击> 此表将在此SQL查询中加入,因此请尝试为我提供最高性能的解决方案。假设Table1将包含数百万条记录。

SELECT 
(many columns)
FROM Table1
LEFT JOIN Table2 ON Table1.Table2ID = Table2.ID
LEFT JOIN Table3 ON ....
LEFT JOIN Table4 ON (Table2.ID = Table4.Table2ID and Table4.LocaleID = 127 and Table4.Type = 0)
LEFT JOIN **the query above** AS vTable1 ON  vTable1.ItemID = Table1.ID
WHERE Table1.CheckID IN (SELECT ID FROM Checks WHERE ....)

修改:这是正在运行的查询,但我不确定它是最有效的。 LinkingTable有大约200,000条记录,运行时间为6秒。

SELECT DISTINCT lt.ItemID, t.EntryDateTime,  t.varchar, t.int
FROM LinkingTable lt 
     LEFT JOIN Transactions t ON t.id = (SELECT Top 1 t2.id FROM LinkingTable lt2
LEFT JOIN Transactions t2 on lt2.TransactionID = t2.ID
where lt2.ItemID = lt.ItemID ORDER BY t2.PrintTime DESC)

4 个答案:

答案 0 :(得分:1)

试试这个,

SELECT i.*, outerT.EntryDateTime, outerT.varchar, outerT.int
FROM Item i
     LEFT JOIN
     (SELECT ItemId AS outerItemId, EntryDateTime, varchar, int
      FROM (SELECT ROW_NUMBER() OVER (PARTITION BY lt.ItemId ORDER BY t.EntryDateTime) AS RowNumber, lt.ItemId, t.EntryDateTime, t.varchar, t.int
            FROM Tranaction t INNER JOIN LinkingTable lt ON lt.TransactionId = t.ID) innerT
      WHERE RowNumber = 1) outerT ON outerT.outerItemId = Item.ID

希望这能解决您的问题

答案 1 :(得分:1)

即使有超过百万条记录,您也会有一些性能点击,但我会根据(ItemID,Primary Key)确保事务表的索引和索引。主键的原因而不是日期 - 如果它自动递增,并且它在事务发生时标记了日期/时间,它们将是本质上的,一个在同一个中。文件中的最后一个条目将始终具有最新日期。也就是说,ID列应该比索引更快,而不是日期/时间。这也可以防止需要查看最近日期的BOTH元素以及与该日期关联的事务ID。以下是我首次尝试查询的方法。

select 
      I.*,
      T2.*
   from
      Item I
         JOIN 
            ( select T.ItemID, MAX( T.PrimaryKey ) as LastEntryPerItem 
                 from Transactions T
                 group by T.ItemID ) MaxPerItem
            ON I.ItemID = T.ItemID

            JOIN Transactions T2
               on MaxPerItem.LastEntryPerItem = T2.PrimaryKey
   order by
      whatever

答案 2 :(得分:0)

select lt.ItemId, t.entrydatetime, t.varchar, t.int
from LinkingTable lt
left join transactions t 
     on lt.transactionId = t.id
        and t.entryDateTime = (select max(t.EntryDateTime)
                               from transactions t2
                               where t2.id = t.id)
我之前有过类似的问题 (SQL Join to get value belong with most recent date)。 JNK的另一个解决方案涉及两个可能更快的连接。我发布在下面。您需要进行测试,看看哪个效果更好。

select lt.ItemId, t.entrydatetime, t.varchar, t.int
from LinkingTable lt
inner join transactions t 
   on lt.ItemId= t.ItemId
Inner join (SELECT ItemId, MAX(entrydatetime) entrydatetime
            FROM transactions t2
            GROUP BY ItemId) SubQ
ON SubQ.ItemId= t.ItemId
AND SubQ.entrydatetime= t.entrydatetime

答案 3 :(得分:0)

为什么不创建一个包含所有“多列”的视图,然后针对该视图运行查询?