MySQL 按空值和非空值分组
MySQL group by null and not null values
我有一个 table 这样的:
id | cluster_id | user_id | name | ...
1 | 1 | 1 | test name
2 | 1 | 3 | other
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
6 | 1 | 1 | baz
我想创建一个按 cluster_id
列分组但仅按具有非空值的列分组的查询,以便我得到如下内容:
id | cluster_id | user_id | ...
1 | 1 | 1 | test name
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
我想要一个具有不同 cluster_ids 的列表,但仅在 cluster_id 不为空的情况下。另外我想过滤任意列,如 user_id
.
在上面的结果中,我还查询了 user_id
,其中 user_id
是 1。
如何创建这样的查询?
提前致谢!
查询简单
GROUP BY 也适用于 NULL 值
我做了两个查询,第一个包含 user_id 最后一个不包含
您必须使用 id 作为主键进行测试,看看排除 NULL 是否会带来一些性能
CREATE TABLE tab1 (
`id` INTEGER,
`cluster_id` int,
`user_id` INTEGER,
`name` VARCHAR(20)
);
INSERT INTO tab1
(`id`, `cluster_id`, `user_id`, `name`)
VALUES
('1', '1', '1', 'test name'),
('2', '1', '3', 'other'),
('3', null, '1', 'one more'),
('4', '2', '1', 'foo'),
('5', null, '1', 'bar'),
('6', '1', '1', 'baz');
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 GROUP BY `cluster_id`,`user_id`)
UNION
SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name
-: | ---------: | ------: | :--------
1 | 1 | 1 | test name
2 | 1 | 3 | other
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 WHERE `cluster_id` IS NOT NULL GROUP BY `cluster_id`,`user_id`)
UNION
SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name
-: | ---------: | ------: | :--------
1 | 1 | 1 | test name
2 | 1 | 3 | other
4 | 2 | 1 | foo
3 | null | 1 | one more
5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 GROUP BY `cluster_id`)
UNION
SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name
-: | ---------: | ------: | :--------
1 | 1 | 1 | test name
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 WHERE `cluster_id` IS NOT NULL GROUP BY `cluster_id`)
UNION
SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name
-: | ---------: | ------: | :--------
1 | 1 | 1 | test name
4 | 2 | 1 | foo
3 | null | 1 | one more
5 | null | 1 | bar
db<>fiddle here
我有一个 table 这样的:
id | cluster_id | user_id | name | ...
1 | 1 | 1 | test name
2 | 1 | 3 | other
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
6 | 1 | 1 | baz
我想创建一个按 cluster_id
列分组但仅按具有非空值的列分组的查询,以便我得到如下内容:
id | cluster_id | user_id | ...
1 | 1 | 1 | test name
3 | null | 1 | one more
4 | 2 | 1 | foo
5 | null | 1 | bar
我想要一个具有不同 cluster_ids 的列表,但仅在 cluster_id 不为空的情况下。另外我想过滤任意列,如 user_id
.
在上面的结果中,我还查询了 user_id
,其中 user_id
是 1。
如何创建这样的查询?
提前致谢!
查询简单
GROUP BY 也适用于 NULL 值
我做了两个查询,第一个包含 user_id 最后一个不包含
您必须使用 id 作为主键进行测试,看看排除 NULL 是否会带来一些性能
CREATE TABLE tab1 ( `id` INTEGER, `cluster_id` int, `user_id` INTEGER, `name` VARCHAR(20) );
INSERT INTO tab1 (`id`, `cluster_id`, `user_id`, `name`) VALUES ('1', '1', '1', 'test name'), ('2', '1', '3', 'other'), ('3', null, '1', 'one more'), ('4', '2', '1', 'foo'), ('5', null, '1', 'bar'), ('6', '1', '1', 'baz');
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 GROUP BY `cluster_id`,`user_id`) UNION SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name -: | ---------: | ------: | :-------- 1 | 1 | 1 | test name 2 | 1 | 3 | other 3 | null | 1 | one more 4 | 2 | 1 | foo 5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 WHERE `cluster_id` IS NOT NULL GROUP BY `cluster_id`,`user_id`) UNION SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name -: | ---------: | ------: | :-------- 1 | 1 | 1 | test name 2 | 1 | 3 | other 4 | 2 | 1 | foo 3 | null | 1 | one more 5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 GROUP BY `cluster_id`) UNION SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name -: | ---------: | ------: | :-------- 1 | 1 | 1 | test name 3 | null | 1 | one more 4 | 2 | 1 | foo 5 | null | 1 | bar
SELECT * FROM tab1 WHERE `id` IN (SELECT MIN(`id`) FROM tab1 WHERE `cluster_id` IS NOT NULL GROUP BY `cluster_id`) UNION SELECT * FROM tab1 WHERE `cluster_id` IS NULL
id | cluster_id | user_id | name -: | ---------: | ------: | :-------- 1 | 1 | 1 | test name 4 | 2 | 1 | foo 3 | null | 1 | one more 5 | null | 1 | bar
db<>fiddle here