我有一个存储出价的下表
╔════════════╦═══════════╦══════════════════════╗
║ lot_id ║ user_id ║ date ║
╠════════════╬═══════════╬══════════════════════╣
║ 123 ║ 9001 ║ 2017-08-09 14:33:55 ║
║ 123 ║ 9005 ║ 2017-08-09 14:33:55 ║
║ 123 ║ 9001 ║ 2017-08-09 14:44:55 ║
║ 124 ║ 8012 ║ 2017-08-09 14:55:55 ║
║ 124 ║ 9001 ║ 2017-08-09 14:55:55 ║
║ 124 ║ 9076 ║ 2017-08-09 14:66:55 ║
╚════════════╩═══════════╩══════════════════════╝
这个想法不是要显示user_id(出于安全原因),而是要显示用户序号(顺序?),具体取决于他下标的时间。
我需要一个查询,该查询将根据first bidder
返回second bidder
,N bidder
,date
。
用PHP这样做效率很低。
P.S。提出问题有点困难,因此欢迎提出任何有关问题标题的建议。
更新
行号不起作用。如果同一用户进行多次出价,则数字应相同。例如,如果同一位用户将第一个出价设为第10个出价,则应显示first bidder
答案 0 :(得分:3)
您可以使用子查询根据日期为每个user_id分配一个数字。
然后将那个子查询加入到bids表中,并使用该投标人的号码。
示例:
-- Sample data
create table bidstable (lot_id int, user_id int, `date` datetime);
insert into bidstable (lot_id, user_id, `date`) values
(123,9001,'2017-08-09 14:33:55'),
(123,9005,'2017-08-09 14:33:55'),
(123,9001,'2017-08-09 14:44:55'),
(124,8012,'2017-08-09 14:55:55'),
(124,9001,'2017-08-09 14:55:55'),
(124,9076,'2017-08-09 14:56:55');
SELECT lot_id, concat('bidder ', n) as bidder, `date`
FROM bidstable AS bids
JOIN (
SELECT user_id, @n := @n + 1 as n
FROM bidstable
CROSS JOIN (SELECT @n := 0) vars
GROUP BY user_id
ORDER BY MIN(`date`), user_id
) AS bidders ON bidders.user_id = bids.user_id
ORDER BY `date`;
SQL Fiddle测试here
答案 1 :(得分:1)
这是一种效率低下的暴力解决方案,无法按(最早)时间对用户进行排名。好的一面是它不使用用户变量或嵌套的ORDER BY,它们可能会产生unexpected results:
SELECT bids.lot_id, CONCAT('Bidder ', ranks.rank, ' (', bids.user_id, ')'), bids.date
FROM bids
INNER JOIN (
SELECT curr.user_id, COUNT(prev.user_id) + 1 AS rank
FROM (
SELECT user_id, MIN(DATE) AS min_date
FROM bids
GROUP BY user_id
) AS curr
LEFT JOIN (
SELECT user_id, MIN(DATE) AS min_date
FROM bids
GROUP BY user_id
) AS prev ON prev.min_date < curr.min_date
GROUP BY curr.user_id
) AS ranks ON bids.user_id = ranks.user_id