选择第一行但仅限于多个匹配项?

时间:2013-09-19 16:06:57

标签: mysql sql

鉴于下面的表`users`:

+----+---------+--------+
| id | name    | office |
+----+---------+--------+
|  1 | David   |      1 |
|  2 | Roz     |      1 |
|  3 | Patrick |      2 |
|  4 | Chris   |      3 |
|  5 | Agnes   |      3 |
|  6 | Freya   |      3 |
+----+---------+--------+

我想选择任何一个办公室的第一个用户,但只有当有多个用户时才这样做,所以:

  • 办公室1 =用户1(大卫)
  • Office 2 = NULL
  • Office 3 =用户4(Chris)

有些事情:

SET @office_id = 2;
SELECT *
  FROM `users`
WHERE `office` = @office_id AND number-of-users-for-office > 1
ORDER BY `id` ASC
LIMIT 1;

3 个答案:

答案 0 :(得分:3)

SELECT  a.office, 
        MAX(
        CASE WHEN b.ID IS NULL
            THEN NULL
            ELSE a.Name
        END) Name
FROM    Tablename a
        LEFT JOIN
        (
            SELECT  office, MIN(id) ID
            FROM    Tablename
            GROUP   BY office
            HAVING  COUNT(*) > 1
        ) b ON  a.office = b.office AND
                a.ID = b.ID
-- WHERE .......                       -- (if you have extra conditions)
GROUP   BY a.office

输出

╔════════╦════════╗
║ OFFICE ║  NAME  ║
╠════════╬════════╣
║      1 ║ David  ║
║      2 ║ (NULL) ║
║      3 ║ Chris  ║
╚════════╩════════╝

子查询的目的是为每个Office获取最少的ID。额外的HAVING子句仅过滤在特定办公室内拥有多个员工的记录。

然后通过User在子查询上加入表LEFT JOIN以获取表中的所有办公室。记录使用MAX()MIN() )进行汇总,以获取每office条的单条记录。

答案 1 :(得分:0)

我想出了另一个我正在为后人写的解决方案。

-- Office id...
SET @office_id = 1;
-- Find the latest user
SELECT `id` INTO @latest_user_id
    FROM `users`
    WHERE `office` = @office_id
    ORDER BY `id` DESC
LIMIT 1;
-- Find the first user that isn't the first
SELECT `id` INTO @latest_user_id
    FROM `users`
    WHERE `office` = @office_id AND `id` != @latest_user_id
    ORDER BY `id` ASC
LIMIT 1;

SQL Fiddle Demo

这个选择最新的,然后尝试选择第一个与最新版本不同的版本。因此,如果只有一行,您将根据需要获得NULL。

答案 2 :(得分:-1)

修改

SELECT `office`,if(count(`id`)>1,name,'NULL') as name
FROM (SELECT * FROM `tablename` ORDER BY id ASC)
`tablename`
GROUP BY `office`
ORDER BY `id` ASC