2017-01-03 91 views
0

我在MySQL中正確執行group_concat()函數時遇到問題。我的數據庫中有實體,這些實體都是行爲主體。某些操作需要處理細節,這些細節作爲處理的標識提供。我的處理細節可能是一些主要處理的一個孩子,在20dB此表示爲使用MySQL group_concat函數'union'和'in'where where子句

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))) 

這個子句按預期工作,直到我嘗試添加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 

這表示查詢不工作,直到我在子查詢的GROUP_CONCAT()的末尾添加

limit 1 

。如果只有一個人被分配到該行動中,這不會成爲問題,但不幸的是,情況並非如此。

我的問題是 - 有沒有辦法讓這兩個工作?

我的示例數據看起來像這樣:

entity_table

entity_id 
1 
2 
3 

entity_action表

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 

處理表

processing_id|parent_id 
      15|  5 
      17|  5 

如果我問所有生產工程過程與5 PARENT_ID GS在這種情況下,我期望的結果將是

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; 
+1

請告訴我們示例表的數據和預期的輸出。 –

+1

這看起來像是一個瘋狂的慢速查詢。嵌套'IN'子查詢可能是我能想象的最慢的事情。我猜這個查詢可以重新設計,以利用'JOIN'並且更快,更方便。首先要改進,使用'AS'(別名)。 – DanFromGermany

+0

你能顯示完整的查詢嗎?我懷疑你要做的是用IN來對付GROUP_CONCAT的結果。這不會工作,因爲GROUP_CONCAT返回一個字符串,而不是一個值列表。 – Kickstart

回答

0

有更多一臉在這現在。

我想你基本的查詢可以消除一些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內的選擇子查詢。以前從未見過任何人嘗試過這種方式,並且該手冊沒有在GROUP CONCAT中提到任何有關此事的信息。然而,當我玩這樣的語法時,看起來MySQL很困惑,因爲它有一個在SELECT中返回多行的子查詢,並且這會導致錯誤。這就是爲什麼它在您向子查詢添加LIMIT 1時起作用的原因,因爲它強制它返回一行。

我的清理查詢遭受同樣的。

可能會清除它,只是在主查詢中對用戶和實體操作進行連接,但對數據不確定。

你可以做的是加入對一個子查詢來獲取所有各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; 
+0

在我的情況下,我需要將內部連接更改爲左連接,因爲實體可能沒有附加任何處理。儘管如此,加入內部的子查詢似乎正在工作,謝謝。 – Luigius

0

嘗試以下查詢:

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;