予備観察
元のクエリは、読みやすくするために次のように再フォーマットできます。
SELECT listings.end_date,
listings.user_id,
listings.title,
listings.auc_fp,
listings.id,
listings.auc_image1
FROM listings
JOIN (SELECT listing_id,
user_id,
bid maxBid
FROM bids
WHERE bid NOT IN (SELECT MAX(bid) FROM bids)
GROUP BY listing_id, user_id
) AS bids
ON listings.id = bids.listing_id
WHERE bids.user_id = 1
AND listings.end_date > NOW()
ORDER BY listings.list_ts DESC
エイリアス化された列maxBid
は、必ずしもリストの最高入札額ではないことに注意してください。このクエリも、まだ開いているリスティング専用です。期待される答えが得られるとは確信していません。除外される唯一の入札は、あらゆるリストの全体的な最高入札を含む入札です。
TDQD — テスト駆動クエリ設計
本当の問題は次のとおりです。
$userid (= 1) が入札を行い、最高入札者である、現在開かれているすべてのリストを検索します。
TDQD を実行する時が来ました — テスト駆動クエリ設計。私の脳は、一度にすべてを行うのに十分な速さで働いていません。
各出品の最高入札額
SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
最大入札を行ったユーザーがユーザー 1 であるリストの入札を検索します。
SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1
最高額の入札を行ったユーザーがユーザー 1 であるリストを検索する
SELECT l.*
FROM listings AS l
JOIN (SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1
) AS u
ON l.id = u.listing_id
クエリを開いているリストに限定する
SELECT l.*
FROM listings AS l
JOIN (SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1
) AS u
ON l.id = u.listing_id
WHERE l.end_date > NOW()
関心のある正確な列に置き換えることができますし、そうすべき*
です。入札の詳細が必要な場合は、それらも取得できます。
Informix に対するテスト
マイナーな構文変更が必要です — NOW() は CURRENT YEAR TO SECOND に置き換えられます — しかし、それは最後のクエリにのみ影響します。構文をより DBMS に依存しない形式にするには、DDL でさらに多くの作業が必要でした。MySQL にはいくつかの奇妙な規則があります。
今後の読者への注意:同じ結果が得られるように、NOW()
またはCURRENT YEAR TO SECOND
を値に置き換えてください。2012-12-29 12:37:43
データ内のリストは、'2013-01-10 00:00:001 以降に失効します。
クエリ 1:
SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id;
出力 1:
listing_id maxbid
34 95.37
40 103.00
38 507.00
41 94.00
48 76.00
6469 22.00
6472 5.00
37 511.00
31 100.00
クエリ 2:
SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1;
出力 2:
listing_id
34
37
48
6469
6472
クエリ 3:
SELECT l.end_date, l.user_id, l.title, l.id
FROM listings AS l
JOIN (SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1
) AS u
ON l.id = u.listing_id;
出力 3: end_date user_id title id 2013-01-09 08:11:16 1 クリスマス ツリー 6469 2013-01-11 09:17:31 3 別のテスト項目 6472
クエリ 4
SELECT l.end_date, l.user_id, l.title, l.id
FROM listings AS l
JOIN (SELECT b.listing_id
FROM bids AS b
JOIN (SELECT listing_id, MAX(bid) AS maxBid
FROM bids
GROUP BY listing_id
) AS m
ON m.listing_id = b.listing_id AND m.maxBid = b.bid
WHERE b.user_id = 1
) AS u
ON l.id = u.listing_id
WHERE l.end_date > CURRENT YEAR TO SECOND;
出力 4:
end_date user_id title id
2013-01-09 08:11:16 1 Christmas Tree 6469
2013-01-11 09:17:31 3 Another test item 6472