1

ここでやろうとしていることのサンプルを上げました

http://sqlfiddle.com/#!2/514d2/2

このデモは、listing_id ごとの最高入札額ではない「bids」テーブルのすべての行を検索します。私がしなければならないことは、$userid (この場合はユーザー 1) が最高入札者であるすべてのリストを見つけることです。

誰かがこれを理解するのを手伝ってくれますか?

SQLFiddle を使用しない場合...

  • テーブル名: リスト
  • テーブル名: 入札

SQL:

SELECT listings.end_date, 
    listings.user_id, 
    listings.title, 
    listings.auc_fp, 
    listings.id, 
    listings.auc_image1 
FROM listings 
INNER 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) 
    bids ON 
      listings.id = bids.listing_id 
  WHERE bids.user_id=1 
  AND listings.end_date > NOW() 
  ORDER BY listings.list_ts DESC

このクエリは、$userid が入札したすべてのリストを正常に検索しますが、最高入札者ではありません。$userid が入札し、IS が最高入札者であるすべてのリストを検索したいと思います。

4

2 に答える 2

2

予備観察

元のクエリは、読みやすくするために次のように再フォーマットできます。

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
于 2012-12-29T20:04:49.263 に答える
1

これにより、左結合を使用して必要な処理を実行し、各製品にこれ以上の入札がないようにする必要があります。

SELECT DISTINCT listings.end_date, listings.user_id, listings.title, 
       listings.auc_fp, listings.id, listings.auc_image1
FROM listings 
JOIN bids b1 
  ON b1.listing_id=listings.id 
LEFT JOIN bids b2 
  ON b2.listing_id=listings.id AND b1.bid < b2.bid
WHERE b1.user_id = 1
  AND b2.bid IS NULL
  AND listings.end_date > NOW()

でテストするオリジナルに基づくSQLfiddle

于 2012-12-29T19:55:04.550 に答える