1

我已经放了一个我在这里尝试做的样本

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

此演示查找“bids”表中不是每个listing_id 最高出价的所有行。我需要做的是找到所有列表,其中 $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 出价并且是最高出价者的所有列表。

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 替换——但这只会影响最后一个查询。在 DDL 上需要做更多的工作才能将语法转换为更接近 DBMS 中立的格式。MySQL 有一些奇怪的约定。

未来读者请注意:将NOW()or替换为CURRENT YEAR TO SECOND诸如2012-12-29 12:37:43获得相同结果的值。数据中的列表从 2013-01-10 00:00:001 开始过期。

查询一:

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 回答