1

とりわけ、lowest_bid 列とhighest_bid 列の両方を持つ select ステートメントの出力を作成したいと考えています。私はその方法を少し知っていますが、ユーザー (user_firstname と user_lastname を独自の列に結合したもの) を low_bidder と maximum_bidder として表示したいです。私がこれまでに持っているものは次のとおりです。

select item_name, item_reserve, count(bid_id) as number_of_bids, 
       min(bid_amount) as lowest_bid, ???, max(big_amount) as highest_bid,
       ???
       from vb_items
       join vb_bids on item_id=bid_item_id
       join vb_users on item_seller_user_id=user_id
       where bid_status =  ‘ok’ and
          item_sold = ‘no’
       sort by item_reserve

(??? は、そこに何を配置するかを理解したら、列を配置する場所です!)

4

3 に答える 3

1

私は、次の利点があるため、このような状況で Common Table Expressions (CTE) を使用することを大いに気に入っています。

  • ロジックのさまざまな部分を分離し、可読性を高めます。
  • 複雑さの軽減 (たとえば、多数のフィールドを GROUP BY する必要や、同じ結合を複数回繰り返す必要があるなど)。

したがって、私の提案するアプローチは次のようなものになります。

-- semi-colon must precede CTE
;

-- collect bid info  
WITH item_bids AS (
  SELECT 
    i.item_id, i.item_name, i.item_reserve, b.bid_id, b.bid_amount, 
    (u.first_name + ' ' + u.last_name) AS bid_user_name
  FROM vb_items i
    JOIN vb_bids b ON i.item_id = b.bid_item_id
    JOIN vb_users u ON b.user_id = u.user_id
  WHERE b.bid_status = 'ok'
    AND i.item_sold = 'no'
), 

-- group bid info
item_bid_info AS ( 
  SELECT item_id, item_name, item_reserve
    COUNT(bid_id) AS number_of_bids, MIN(bid_amount) AS lowest_bid, MAX(bid_amount) AS highest_bid
  FROM item_bids
  GROUP BY item_id, item_name, item_reserve
)

-- assemble final result
SELECT 
  bi.item_name, bi.item_reserve, bi.number_of_bids, 
  bi.low_bid,  low_bid.bid_user_name AS low_bid_user, 
  bi.high_bid, high_bid.bid_user_name AS high_bid_user
FROM item_bid_info bi
  JOIN item_bids AS low_bid  ON bi.lowest_bid = low_bid.bid_amount  AND bi.item_id = low_bid.bid_item_id
  JOIN item_bids AS high_bid ON bi.lowest_bid = high_bid.bid_amount AND bi.item_id = high_bid.bid_item_id
ORDER BY bi.item_reserve;

SQL ステートメント全体 (先頭から のWITH後の最後のセミコロンまでORDER BY) は単一のステートメントであり、オプティマイザーによってそのように評価されることに注意してください。(一部の人々は、一時テーブルのように各部分が個別に評価され、すべての行が最後のステップで最後に結合されると考えています。それはどのように機能するかではありません。CTE はサブクエリと同じくらい効率的です。)

また、このアプローチはJOIN入札金額に基づいているため、1 つのアイテムに対して同じ入札があった場合は失敗することに注意してください。(とにかく、それは無効な状態であるべきだと思われますよね?) また、以下に応じて効率上の懸念があるかもしれません:

  • あなたのテーブルのサイズ
  • ルックアップでインデックスを使用できるかどうか

一意の制約を含めることで両方の問題に対処できます (これには、外部キーのbid_item_idにもインデックスを付けるという追加の利点があります。常に良い方法です):

ALTER TABLE [dbo].[vb_bids] ADD  CONSTRAINT [UK_vbBids_item_amount] 
UNIQUE NONCLUSTERED (bid_item_id, bid_amount)
GO

それが役立つことを願っています!

于 2013-10-04T00:40:48.103 に答える