在 where 子句中将 MySQL group_concat 函数与 'union' 和 'in' 一起使用
Using MySQL group_concat function with 'union' and 'in' in where clause
我在 MySQL 中正确执行 group_concat() 函数时遇到问题。我的数据库中有受操作影响的实体。某些操作需要处理细节,这些细节作为处理的 id 提供。我的处理细节可能是一些主要处理的子项,在数据库中表示为
parent_id
在我的查询中,我向数据库询问已被所有子进程处理过的所有实体,这些实体与我的起始实体的处理方式相同 parent_id(我事先获得了包含所有信息的单个实体).
在数据库中,where 子句如下所示:
where p.processing_id in
(SELECT processing_id FROM processing_type_1 where parent_id in
(select parent_id from processing_type_1 where parent_id in (p.processing_id)))
union all (SELECT processing_id FROM processing_type_2 where parent_id =
(select parent_id from processing_type_2 where parent_id in (p.processing_id)))
在我尝试在 select 子句中添加 group_concat() 之前,该子句按预期工作。实体上的每个动作都有分配给它的人员,我需要让所有的人都分配给某些动作。
select 子句如下所示:
group_concat(distinct (select z.full_name from user z join entity_action ea on z.id = ea.personnel_id where ea.entity_id = e.id and ea.action_type = 'some_action' order by z.full_name) separator ', ') as action_personnel
在我添加
之前,上述查询不起作用
limit 1
在 group_concat() 中子查询的末尾。如果只有一个人被分配到行动中,这不会是一个问题,但不幸的是,情况并非如此。
我的问题是 - 有没有办法让这两个工作?
我的示例数据如下所示:
entity_table
entity_id
1
2
3
entity_action table
action_id|entity_id| action_name|personnel_id|processing_id
1| 1|'some action'| 1| 15
2| 1| 'other'| 1|
3| 1| 'another'| 2|
4| 1|'some action'| 3| 17
处理中table
processing_id|parent_id
15| 5
17| 5
如果我询问所有 parent_id 为 5 的处理,在这种情况下我想要的结果将是
entity_id|action_personnel
1| 1,3
我的完整查询如下:
SELECT e.entity_id,
group_concat(distinct (select z.full_name from user z join entity_action ea on z.id = ea.personnel_id where ea.entity_id = e.id and ea.action_type = 'some_action' order by z.full_name) separator ', ') as action_personnel
FROM enity e
inner join entity_action ea on ea.entity_id = e.entity_id
left outer join processing p on p.id = ea.entity_id
where
(1 IS null OR
p.processing_id in
(SELECT processing_id FROM processing_type_1 where parent_id in
(select parent_id from processing_type_1 where parent_id in (p.processing_id)))
union all (SELECT processing_id FROM processing_type_2 where parent_id =
(select parent_id from processing_type_2 where parent_id in (p.processing_id)))
)
group by e.entity_id;
尝试以下查询:
SELECT e.entity_id,
GROUP_CONCAT(DISTINCT z.full_name ORDER BY z.full_name) SEPARATOR ', ') AS action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
LEFT OUTER JOIN processing p ON p.id = ea.entity_id
LEFT JOIN `user` z ON z.id = ea.personnel_id AND ea.action_type = 'some_action'
WHERE
(1 IS NULL OR
p.processing_id IN
(SELECT processing_id FROM processing_type_1 WHERE parent_id IN
(SELECT parent_id FROM processing_type_1 WHERE parent_id IN (p.processing_id)))
UNION ALL (SELECT processing_id FROM processing_type_2 WHERE parent_id =
(SELECT parent_id FROM processing_type_2 WHERE parent_id IN (p.processing_id)))
)
GROUP BY e.entity_id;
现在更深入地了解了这一点。
我认为您的基本查询可以像这样消除一些 IN 子句(但这不会起作用)
SELECT e.entity_id,
GROUP_CONCAT((SELECT DISTINCT z.full_name FROM user z INNER JOIN entity_action ea ON z.id = ea.personnel_id WHERE ea.entity_id = e.id AND ea.action_type = 'some_action') ORDER BY full_name SEPARATOR ', ') AS action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
WHERE (1 IS NULL
OR p.processing_id in
(
SELECT processing_id
FROM processing_type_1 pt1_a
INNER JOIN processing_type_1 pt1_b
ON pt1_a.parent_id = pt1_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt1_b.parent_id = p.processing_id
UNION
SELECT processing_id pt2_a
FROM processing_type_2
INNER JOIN processing_type_2 pt2_b
ON pt2_a.parent_id = pt2_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt2_b.parent_id = p.processing_id
)
)
GROUP BY e.entity_id;
看一下,您在 GROUP_CONCAT 中的 SELECT 中有一个子查询。以前从未见过有人尝试过这个,并且手册在 GROUP CONCAT 中没有提及任何相关内容。但是,当我使用这种语法时,MySQL 似乎很困惑,因为它在 SELECT 中有一个子查询 returning 多行,这会导致错误。这就是当您将 LIMIT 1 添加到子查询时它起作用的原因,因为它强制它 return 一行。
我清理后的查询也有同样的问题。
可能可以清理它以仅在主查询中执行用户和实体操作的连接,但不确定您的数据。
你可以做的是加入一个子查询,以获得每个 entity_id:-
的所有全名组合在一起
SELECT e.entity_id,
sub1.action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
INNER JOIN
(
SELECT ea.entity_id,
GROUP_CONCAT(DISTINCT z.full_name ORDER BY full_name SEPARATOR ', ') AS action_personnel
FROM user z
INNER JOIN entity_action ea
ON z.id = ea.personnel_id
WHERE ea.entity_id = e.id
AND ea.action_type = 'some_action'
GROUP BY ea.entity_id
) sub1
ON sub1.entity_id = e.id
WHERE (1 IS NULL
OR p.processing_id in
(
SELECT processing_id
FROM processing_type_1 pt1_a
INNER JOIN processing_type_1 pt1_b
ON pt1_a.parent_id = pt1_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt1_b.parent_id = p.processing_id
UNION
SELECT processing_id pt2_a
FROM processing_type_2
INNER JOIN processing_type_2 pt2_b
ON pt2_a.parent_id = pt2_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt2_b.parent_id = p.processing_id
)
)
GROUP BY e.entity_id;
我在 MySQL 中正确执行 group_concat() 函数时遇到问题。我的数据库中有受操作影响的实体。某些操作需要处理细节,这些细节作为处理的 id 提供。我的处理细节可能是一些主要处理的子项,在数据库中表示为
parent_id
在我的查询中,我向数据库询问已被所有子进程处理过的所有实体,这些实体与我的起始实体的处理方式相同 parent_id(我事先获得了包含所有信息的单个实体).
在数据库中,where 子句如下所示:
where p.processing_id in
(SELECT processing_id FROM processing_type_1 where parent_id in
(select parent_id from processing_type_1 where parent_id in (p.processing_id)))
union all (SELECT processing_id FROM processing_type_2 where parent_id =
(select parent_id from processing_type_2 where parent_id in (p.processing_id)))
在我尝试在 select 子句中添加 group_concat() 之前,该子句按预期工作。实体上的每个动作都有分配给它的人员,我需要让所有的人都分配给某些动作。
select 子句如下所示:
group_concat(distinct (select z.full_name from user z join entity_action ea on z.id = ea.personnel_id where ea.entity_id = e.id and ea.action_type = 'some_action' order by z.full_name) separator ', ') as action_personnel
在我添加
之前,上述查询不起作用limit 1
在 group_concat() 中子查询的末尾。如果只有一个人被分配到行动中,这不会是一个问题,但不幸的是,情况并非如此。
我的问题是 - 有没有办法让这两个工作?
我的示例数据如下所示:
entity_table
entity_id
1
2
3
entity_action table
action_id|entity_id| action_name|personnel_id|processing_id
1| 1|'some action'| 1| 15
2| 1| 'other'| 1|
3| 1| 'another'| 2|
4| 1|'some action'| 3| 17
处理中table
processing_id|parent_id
15| 5
17| 5
如果我询问所有 parent_id 为 5 的处理,在这种情况下我想要的结果将是
entity_id|action_personnel
1| 1,3
我的完整查询如下:
SELECT e.entity_id,
group_concat(distinct (select z.full_name from user z join entity_action ea on z.id = ea.personnel_id where ea.entity_id = e.id and ea.action_type = 'some_action' order by z.full_name) separator ', ') as action_personnel
FROM enity e
inner join entity_action ea on ea.entity_id = e.entity_id
left outer join processing p on p.id = ea.entity_id
where
(1 IS null OR
p.processing_id in
(SELECT processing_id FROM processing_type_1 where parent_id in
(select parent_id from processing_type_1 where parent_id in (p.processing_id)))
union all (SELECT processing_id FROM processing_type_2 where parent_id =
(select parent_id from processing_type_2 where parent_id in (p.processing_id)))
)
group by e.entity_id;
尝试以下查询:
SELECT e.entity_id,
GROUP_CONCAT(DISTINCT z.full_name ORDER BY z.full_name) SEPARATOR ', ') AS action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
LEFT OUTER JOIN processing p ON p.id = ea.entity_id
LEFT JOIN `user` z ON z.id = ea.personnel_id AND ea.action_type = 'some_action'
WHERE
(1 IS NULL OR
p.processing_id IN
(SELECT processing_id FROM processing_type_1 WHERE parent_id IN
(SELECT parent_id FROM processing_type_1 WHERE parent_id IN (p.processing_id)))
UNION ALL (SELECT processing_id FROM processing_type_2 WHERE parent_id =
(SELECT parent_id FROM processing_type_2 WHERE parent_id IN (p.processing_id)))
)
GROUP BY e.entity_id;
现在更深入地了解了这一点。
我认为您的基本查询可以像这样消除一些 IN 子句(但这不会起作用)
SELECT e.entity_id,
GROUP_CONCAT((SELECT DISTINCT z.full_name FROM user z INNER JOIN entity_action ea ON z.id = ea.personnel_id WHERE ea.entity_id = e.id AND ea.action_type = 'some_action') ORDER BY full_name SEPARATOR ', ') AS action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
WHERE (1 IS NULL
OR p.processing_id in
(
SELECT processing_id
FROM processing_type_1 pt1_a
INNER JOIN processing_type_1 pt1_b
ON pt1_a.parent_id = pt1_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt1_b.parent_id = p.processing_id
UNION
SELECT processing_id pt2_a
FROM processing_type_2
INNER JOIN processing_type_2 pt2_b
ON pt2_a.parent_id = pt2_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt2_b.parent_id = p.processing_id
)
)
GROUP BY e.entity_id;
看一下,您在 GROUP_CONCAT 中的 SELECT 中有一个子查询。以前从未见过有人尝试过这个,并且手册在 GROUP CONCAT 中没有提及任何相关内容。但是,当我使用这种语法时,MySQL 似乎很困惑,因为它在 SELECT 中有一个子查询 returning 多行,这会导致错误。这就是当您将 LIMIT 1 添加到子查询时它起作用的原因,因为它强制它 return 一行。
我清理后的查询也有同样的问题。
可能可以清理它以仅在主查询中执行用户和实体操作的连接,但不确定您的数据。
你可以做的是加入一个子查询,以获得每个 entity_id:-
的所有全名组合在一起SELECT e.entity_id,
sub1.action_personnel
FROM enity e
INNER JOIN entity_action ea ON ea.entity_id = e.entity_id
INNER JOIN
(
SELECT ea.entity_id,
GROUP_CONCAT(DISTINCT z.full_name ORDER BY full_name SEPARATOR ', ') AS action_personnel
FROM user z
INNER JOIN entity_action ea
ON z.id = ea.personnel_id
WHERE ea.entity_id = e.id
AND ea.action_type = 'some_action'
GROUP BY ea.entity_id
) sub1
ON sub1.entity_id = e.id
WHERE (1 IS NULL
OR p.processing_id in
(
SELECT processing_id
FROM processing_type_1 pt1_a
INNER JOIN processing_type_1 pt1_b
ON pt1_a.parent_id = pt1_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt1_b.parent_id = p.processing_id
UNION
SELECT processing_id pt2_a
FROM processing_type_2
INNER JOIN processing_type_2 pt2_b
ON pt2_a.parent_id = pt2_b.parent_id
INNER processing p on p.id = ea.entity_id
ON pt2_b.parent_id = p.processing_id
)
)
GROUP BY e.entity_id;