查找在其他两列中的每个唯一值中显示的MIN值

时间:2011-06-30 09:33:18

标签: mysql

给出以下(简化)表:

p

id  name    registered
-----------------------------------
1   Geoff   2011-03-29 12:09:08
2   Phil    2011-04-29 09:03:54
3   Tony    2011-05-29 21:22:23
4   Gary    2011-06-21 22:56:08
...

项目i

date                        p1id    p2id    
----------------------------------------
2011-06-29 20:09:44         1       2
2011-06-26 10:45:00         1       3
2011-06-23 12:22:43         2       3
2011-06-22 13:07:12         2       4
...

我想:     每个i.date出现在 p.idp1id中的最早单p2id;如果两者都没有,则为p.registered

到目前为止,我已经尝试过了:

CREATE TEMPORARY TABLE temp (id INT);
INSERT INTO temp (id) 
    SELECT DISTINCT u FROM (
        SELECT p1id AS u FROM Items UNION ALL 
        SELECT p2id AS u FROM Items
    )tt;
SELECT registered,id FROM People 
    WHERE id NOT IN (SELECT id FROM temp);

这让我直到第二部分,虽然以一种相当笨拙的方式;除了p.id(ugh)的所有值之外,我在第一部分超越了某种外部的脚本迭代。

有人可以帮忙吗?

我在MySQL 5.1上,有大约20万人和~100k项目。

2 个答案:

答案 0 :(得分:1)

这是在Postgres中测试的,但我认为它应该在MySQL中工作,几乎没有变化:

SELECT p.id,COALESCE(MIN(x.date),p.registered) AS date
FROM p
JOIN (
    SELECT p.id,MIN(i.date) AS date
    FROM p
    JOIN i ON (p.id=i.p1id)
    GROUP BY p.id
UNION
    SELECT p.id,MIN(i.date) AS date
    FROM p
    JOIN i ON (p.id=i.p2id)
    GROUP BY p.id
) AS x ON x.id = p.id
GROUP BY p.id,p.registered;

输出(给出样本数据):

 id |        date         
----+---------------------
  3 | 2011-06-23 12:22:43
  1 | 2011-06-26 10:45:00
  2 | 2011-06-22 13:07:12
  4 | 2011-06-22 13:07:12
(4 rows)

答案 1 :(得分:1)

还有一个解决方案:

SELECT id, name, IF(min_date1 IS NULL AND min_date2 IS NULL, registered, LEAST(COALESCE(min_date1, min_date2), COALESCE(min_date2, min_date1))) date FROM (
  SELECT p.id, p.name, p.registered, MIN(i1.date) min_date1, MIN(i2.date) min_date2 FROM people p
    LEFT JOIN items i1
      ON p.id = i1.p1id
    LEFT JOIN items i2
      ON p.id = i2.p2id
  GROUP BY id
) t;

或者这个:

SELECT p.id, p.name, COALESCE(MIN(i.date), p.registered) FROM people p
  LEFT JOIN (
    SELECT p1id id, date FROM items
      UNION ALL
    SELECT p2id id, date FROM items
  ) i
  ON p.id = i.id
GROUP BY id;

结果:

+------+-------+---------------------+
| id   | name  | date                |
+------+-------+---------------------+
|    1 | Geoff | 2011-06-26 10:45:00 |
|    2 | Phil  | 2011-06-22 13:07:12 |
|    3 | Tony  | 2011-06-23 12:22:43 |
|    4 | Gary  | 2011-06-22 13:07:12 |
+------+-------+---------------------+