根据日期将行号分配给可能重复的行

时间:2018-08-01 12:17:44

标签: mysql sql date

我有一个存储出价的下表

╔════════════╦═══════════╦══════════════════════╗
║ 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 bidderN bidderdate

用PHP这样做效率很低。

P.S。提出问题有点困难,因此欢迎提出任何有关问题标题的建议。

更新 行号不起作用。如果同一用户进行多次出价,则数字应相同。例如,如果同一位用户将第一个出价设为第10个出价,则应显示first bidder

2 个答案:

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

SQL Fiddle