我的一個朋友想出了以下查詢來查找獲勝賭注
SELECT b1.*
FROM bids as b1
LEFT JOIN bids AS b2 ON b1.item_id = b2.item_id AND b1.bid_price < b2.bid_price
WHERE b2.item_id IS NULL
它似乎作業正常,但我不明白它是如何作業的,以及它是偶然還是結果總是相同的。有人可以解釋一下它是如何作業的,尤其是如何b1.bid_price < b2.bid_price與顯然不存在的 b2.bid_price 一起作業?
這是轉儲:
CREATE TABLE `bids` (
`bid_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`bid_price` decimal(10,2) unsigned NOT NULL,
`user_id` int(11) unsigned NOT NULL,
`item_id` int(11) unsigned NOT NULL,
`bid_date_created` datetime NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`bid_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4
INSERT INTO bids VALUES (1, 14000.33, 12, 1, '2021-10-27 19:07:21');
INSERT INTO bids VALUES (2, 13000.60, 6, 1, '2021-10-27 18:07:21');
INSERT INTO bids VALUES (3, 21000.00, 7, 4, '2021-10-29 18:07:21');
INSERT INTO bids VALUES (4, 17000.25, 6, 4, '2021-10-27 18:07:21');
INSERT INTO bids VALUES (6, 5500.00, 6, 7, '2021-11-21 11:46:17');
INSERT INTO bids VALUES (7, 1000.00, 6, 29, '2021-11-22 11:21:41');
INSERT INTO bids VALUES (8, 18000.00, 6, 1, '2021-11-23 11:21:11');
INSERT INTO bids VALUES (9, 110.00, 14, 30, '2021-11-28 15:24:56');
INSERT INTO bids VALUES (10, 120.00, 13, 30, '2021-11-28 15:25:11');
INSERT INTO bids VALUES (11, 159.00, 14, 30, '2021-11-28 15:25:19');
INSERT INTO bids VALUES (12, 170.00, 13, 30, '2021-11-28 15:25:34');
INSERT INTO bids VALUES (13, 200.00, 14, 30, '2021-11-28 15:25:57');
INSERT INTO bids VALUES (14, 250.00, 13, 30, '2021-11-28 15:26:02');
INSERT INTO bids VALUES (15, 6000.00, 14, 6, '2021-11-28 15:26:30');
INSERT INTO bids VALUES (16, 7300.00, 13, 6, '2021-11-28 15:26:44');
INSERT INTO bids VALUES (17, 10000.00, 14, 6, '2021-11-28 15:29:14');
uj5u.com熱心網友回復:
該查詢使用LEFT OUTER JOIN來試圖找到一個行b2匹配相同item_id的b1,但更大的bid_price比值b1。
左外連接的作業方式是,如果沒有匹配項,則b1無論如何都會回傳左表 ( ) 中的列,b2并且 的列為 NULL。如果我們在沒有 WHERE 子句的情況下測驗查詢,您可以在示例資料中看到這一點。
mysql> SELECT b1.bid_id, b1.item_id, b2.bid_id, b2.item_id
FROM bids as b1 LEFT JOIN bids AS b2 ON b1.item_id = b2.item_id
AND b1.bid_price < b2.bid_price;
-------- --------- -------- ---------
| bid_id | item_id | bid_id | item_id |
-------- --------- -------- ---------
| 2 | 1 | 1 | 1 |
| 4 | 4 | 3 | 4 |
| 1 | 1 | 8 | 1 |
| 2 | 1 | 8 | 1 |
| 9 | 30 | 10 | 30 |
| 9 | 30 | 11 | 30 |
| 10 | 30 | 11 | 30 |
| 9 | 30 | 12 | 30 |
| 10 | 30 | 12 | 30 |
| 11 | 30 | 12 | 30 |
| 9 | 30 | 13 | 30 |
| 10 | 30 | 13 | 30 |
| 11 | 30 | 13 | 30 |
| 12 | 30 | 13 | 30 |
| 9 | 30 | 14 | 30 |
| 10 | 30 | 14 | 30 |
| 11 | 30 | 14 | 30 |
| 12 | 30 | 14 | 30 |
| 13 | 30 | 14 | 30 |
| 15 | 6 | 16 | 6 |
| 15 | 6 | 17 | 6 |
| 16 | 6 | 17 | 6 |
| 3 | 4 | NULL | NULL |
| 6 | 7 | NULL | NULL |
| 7 | 29 | NULL | NULL |
| 8 | 1 | NULL | NULL |
| 14 | 30 | NULL | NULL |
| 17 | 6 | NULL | NULL |
-------- --------- -------- ---------
大多數b1行b2與具有相同item_id但更大的某些行匹配bid_price。
在最后六行中,出價b1沒有其他更大的出價bid_price,因此這六個是每個 的最大出價item_id。這些是你想要的結果。
過濾這些的一種簡單方法是使用您看到的 WHERE 子句:
WHERE b2.item_id IS NULL
實際上,您可以使用任何b2已知為非 NULL 的列,因為這意味著它為 NULL 的唯一方法是由于 LEFT OUTER JOIN 而沒有匹配項。
uj5u.com熱心網友回復:
這是正在發生的事情的快速細分:
讓我們從連接本身開始。LEFT JOIN表示它將獲取來自左側 (b1) 的所有結果和來自右側 (b2) 的任何相應結果(如果存在)。如果不是,b2 中的所有列都將為空(請記住這一點,因為它在此查詢的作業方式中起著重要作用)。
接下來,它加入item_id,因此它只獲取該特定專案的價格。然后,它有另一個連接條件,b1.bid_price < b2.bid_price。任何與 的比較NULL最終都將被評估為錯誤。請記住,必須滿足這兩個條件,否則所有行都b2 為空,這b2也代表表中的每個條目bets。這意味著如果b2為空,則它要么是該專案的唯一賭注(由于b1.item_id = b2.item_id約束),要么是最高的(由于b1.bid_price < b2.bid_price約束)。
最后是WHERE條款。如上所述,該JOIN條款的設定非常完美,因此最高出價的NULL值都在 中b2。這使得這部分變得簡單,因為現在WHERE子句可以簡單地獲取連接b2具有NULL值的每個實體。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/368589.html
上一篇:如何在sql表中查找缺失的元素
