如何比较SQL

时间:2016-04-28 01:40:34

标签: sql performance compare db2-luw

我有ITEMS表,其中ITEM_ID列是唯一的:

ITEM_ID | ITEM_NAME | START_VALUE
  A1324 | item1     | 113
  B4534 | item3     | 50
  A3453 | item7     | 35
  A7654 | item2     | 48

下面的BIDS表中没有唯一值:

ITEM_ID | BIDDER_NAME | BID_VALUE | BID_TIME
  A7654 | Jessica     | 53        | 2016-02-02 14:28:43
  B4534 | John        | 69        | 2016-01-03 08:03:06
  B4534 | Annie       | 63        | 2016-01-02 15:23:27
  B4534 | Tim         | 65        | 2016-01-01 18:15:02
  B4534 | AuctionEnd  | 50        | 2016-01-02 19:45:34
  A7654 | Mark        | 52        | 2016-02-02 16:51:12  

我需要连接两个表并插入到结果表中,该结果表具有与ITEMS表相同的行数,并且还包含在AuctionEnd行日期之前生成的最高出价者名称和最高出价。在这种情况下,每个项目可能没有AuctionEnd行,应列出最高出价和出价者。如果特定项目根本没有出价,则此列应为null。对于上表,结果表应如下所示:

 ITEM_ID|ITEM_NAME|START_VALUE|MAX_BIDDER_NAME|MAX_BID_VALUE|BID_TIME
  A1324 | item1   | 113       |null           |null         |0
  B4534 | item3   | 50        |Tim            |65           |2016-01-01 18:15:02
  A3453 | item7   | 35        |null           |null         |0
  A7654 | item2   | 48        |Jessica        |53           |2016-02-02 14:28:43

这应该在DB2v10上运行,但也欢迎任何其他SQL。这些表包含数百万行,因此性能是主要关注的问题。我的方法应该是什么?

2 个答案:

答案 0 :(得分:2)

另一个可能更快的查询如下。 另外,请确保两个表上的ITEM_ID都有索引。

是的...你说错了,我遗漏了允许出价的逻辑>最后的出价时间。下面的代码显示了我的完整工作。诀窍是首先创建一个具有所有VALID BIDS的cte,然后再评估最高出价。

  CREATE TABLE #ITEMS (ITEM_ID varchar(10), ITEM_NAME varchar(10), START_VALUE int)
  INSERT INTO #ITEMS
  VALUES
  ('A1324','item1',113),
  ('B4534','item3',50),
  ('A3453','item7',35),
  ('A7654','item2',48)


  CREATE TABLE #BIDS (ITEM_ID varchar(10), BIDDER_NAME varchar(50), BID_VALUE int, BID_TIME datetime)
  INSERT INTO #BIDS
  VALUES
  ('A7654','Jessica',53,'2016-02-02 14:28:43'),
  ('B4534','John',69,'2016-01-03 08:03:06'),
  ('B4534','Annie',63,'2016-01-02 15:23:27'),
  ('B4534','Tim',65,'2016-01-01 18:15:02'),
  ('B4534','AuctionEnd',50,'2016-01-02 19:45:34'),
  ('A7654','Mark',52,'2016-02-02 16:51:12')


;WITH cteEndTime as
(
    Select 
        ITEM_ID,
        CASE WHEN BIDDER_NAME = 'AuctionEnd' THEN BID_TIME ELSE NULL END as 'END_BID_TIME'
    From #BIDS
    Where BIDDER_NAME = 'AuctionEnd'
)

,cteValidBIDS as
(Select * From (
    Select bd.ITEM_ID, bd.BIDDER_NAME, bd.BID_VALUE, bd.BID_TIME,
        ROW_NUMBER() over (partition by bd.ITEM_ID order by BID_TIME) as 'brnk',
        c.END_BID_TIME
    FROM #BIDS bd
    LEFT JOIN cteEndTime c on c.ITEM_ID = bd.ITEM_ID
) a
Where a.BID_TIME < ISNULL(a.END_BID_TIME, '2200-01-01')
)

,finalCTE as (
Select ITEM_ID, MAX_BID_NAME, MAX_BID_VALUE, BID_TIME From (
    Select
        ROW_NUMBER() over (partition by c.ITEM_ID order by c.BID_VALUE desc) as 'brnk'
        ,c.ITEM_ID
        ,c.BIDDER_NAME as 'MAX_BID_NAME'
        ,c.BID_VALUE as 'MAX_BID_VALUE'
        ,c.BID_TIME
    From cteValidBIDS c
    ) a
    Where a.brnk = 1
)

Select i.ITEM_ID, i.ITEM_NAME, i.START_VALUE, c.MAX_BID_NAME, c.MAX_BID_VALUE, c.BID_TIME
From #ITEMS i
LEFT JOIN finalCTE c on c.ITEM_ID = i.ITEM_ID

答案 1 :(得分:1)

您可以通过计算每个项目的最近出价时间来获取最近的出价(使用max())。然后使用join获取相应的出价:

select i.*, b.*
from items i left join
     (select b.item_id, max(b.bid_time) as maxbt
      from bids b
      where b.bid_time < (select max(b.bid_time)
                          from bids b2
                          where b2.bidder_name = 'AuctionEnd' and
                                b2.item_id = b.item_id
                         )
      group by b.item_id
     ) bb
     on i.item_id = bb.item_id left join
     bids b
     on b.item_item = i.item_id and b.bid_time = b.maxbt;