我使用通用表表達式(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
,所以如果單個商品的出價相同,則會失敗。 (無論如何,這似乎應該是一個無效狀態,但是,對吧?)你也可能因有效率的擔憂:
您可以通過包括唯一約束,解決這兩個問題(其中有索引外鍵bid_item_id還有的附加優勢;總是一個很好的做法):
ALTER TABLE [dbo].[vb_bids] ADD CONSTRAINT [UK_vbBids_item_amount]
UNIQUE NONCLUSTERED (bid_item_id, bid_amount)
GO
希望幫助!
而不是'item_seller_user_id'是否有出價競標'user_id'的列? – Laurence
有一個item_buyer_user_id。 –
如何判斷在出價與用戶之間沒有關聯的情況下誰出價最低? – Laurence