2016-06-11 126 views
1

執行此SELECT語句時,我收到「無效的組函數使用」錯誤。MySQL:嵌套GROUP_CONCAT

SELECT kits.id, kits.is_quote, 
GROUP_CONCAT(
CONCAT_WS('|||', kits_table.id, kits_table.name, 
    GROUP_CONCAT(
     CONCAT_WS('|', parts_table.id, parts_table.name) 
    SEPARATOR '||'), 
    GROUP_CONCAT(
     CONCAT_WS('|', labor_table.id, labor_table.description) 
    SEPARATOR '||') 
) 
SEPARATOR '||||') as kits, 
GROUP_CONCAT(CONCAT_WS('|', parts.id, parts.name) SEPARATOR '|||') as parts, 
GROUP_CONCAT(CONCAT_WS('|', labor.id, labor.description) SEPARATOR '|||') as labor 
FROM kits 
LEFT JOIN kits as kits_table ON kits_table.kit_id = kits.id 
LEFT OUTER JOIN parts as parts_table ON parts_table.kit_id = kits_table.id 
LEFT OUTER JOIN labor as labor_table ON labor_table.kit_id = kits_table.id 
LEFT OUTER JOIN parts ON parts.kit_id = kits.id 
LEFT OUTER JOIN labor ON labor.kit_id = kits.id 
WHERE kits.id = '1' 
GROUP BY kits.id; 

我需要能夠選擇數據庫的工具包,以及包內我需要查詢返回其他套件,部件和人工,與方程的包部分還返回部件和人工。如果我刪除這個GROUP_CONCAT(*) as kits語句,那麼查詢工作正常。

當我使用這些表的要求是與主要信息的表,你需要:

創建表:

CREATE TABLE `kits` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `kit_id` int(11) DEFAULT NULL, 
    `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    `name` varchar(45) DEFAULT NULL, 
    `description` varchar(150) DEFAULT NULL, 
    `quantity` varchar(45) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_UNIQUE` (`id`), 
    KEY `KIT` (`kit_id`) 
) 

CREATE TABLE `labor` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `kit_id` int(11) DEFAULT NULL, 
    `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    `description` varchar(150) NOT NULL, 
    `hours` varchar(45) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_UNIQUE` (`id`), 
    KEY `KIT` (`kit_id`) 
) 

CREATE TABLE `parts` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `kit_id` int(11) DEFAULT NULL, 
    `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    `name` varchar(45) DEFAULT NULL, 
    `description` varchar(150) DEFAULT NULL, 
    `sale_price` varchar(45) DEFAULT '0.00', 
    `quantity` varchar(45) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_UNIQUE` (`id`), 
    KEY `KIT` (`kit_id`) 
) 

和INSERT語句:

INSERT INTO `kits` 
(`id`, 
`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`quantity`) 
VALUES 
(1,0,0,"Main Kit", "Sample Description",1); 

INSERT INTO `kits` 
(`id`, 
`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`quantity`) 
VALUES 
(2,1,0,"Kit within kit", "Sample Description",1); 

INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(1,0,"First Kit Part 1", "Part description","23.5",1); 
INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(1,0,"First Kit Part 2", "Part description","23.5",1); 

INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(2,0,"Kit within kit part 1", "Sample Part Description","23.5",1); 

INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(2,0,"Kit within kit part 2", "Sample Part Description","23.5",1); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(1,0,"First Kit labor 1","1.5"); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(1,0,"First Kit labor 2","1.5"); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(2,0,"Kit within kit labor 1","1.5"); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(2,0,"Kit within kit labor 2","1.5"); 

//Second Kit within kit. 

INSERT INTO `kits` 
(`id`, 
`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`quantity`) 
VALUES 
(3,1,0,"Kit within kit 2", "Sample Description",1); 

INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(3,0,"Kit within kit part 1", "Sample Part Description","23.5",1); 

INSERT INTO `parts` 
(`kit_id`, 
`is_quote`, 
`name`, 
`description`, 
`sale_price`, 
`quantity`) 
VALUES 
(3,0,"Kit within kit part 2", "Sample Part Description","23.5",1); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(3,0,"Kit within kit labor 1","1.5"); 

INSERT INTO `labor` 
(`kit_id`, 
`is_quote`, 
`description`, 
`hours`) 
VALUES 
(3,0,"Kit within kit labor 2","1.5"); 

這裏是使用上述INSERT值的樣本輸出。另外請注意,試劑盒中可以有多個試劑盒,由||||分隔。

+----+----------+----------------------------------------------------------------------------------------------------------------------------+------------------+-------------------+ 
| id | is_quote |               kits               |  parts  |  labor  | 
+----+----------+----------------------------------------------------------------------------------------------------------------------------+------------------+-------------------+ 
| 1 |  0 | 2|||Kit within kit|||2|Kit within kit part 1||3|Kit within kit part 2|||2|Kit within kit labor 1||3|Kit within kit labor 2 | 1|First Kit Part | 1|First Kit labor | 
+----+----------+----------------------------------------------------------------------------------------------------------------------------+------------------+-------------------+ 
+1

請減少到查詢的核心部件您的問題。 –

+0

@juergend更好嗎? – forrestmid

+0

你可以爲我做一個測試,我不能從我自己做。你能否以不同於表名的方式更改你的group_concat的別名? –

回答

2

嘗試:

mysql> SELECT 
    -> GROUP_CONCAT(
    ->  CONCAT_WS('|||', 0, 1, 
    ->    GROUP_CONCAT(CONCAT_WS('|', 2, 3) SEPARATOR '||') 
    ->    ) 
    ->   ) `test`; 
ERROR 1111 (HY000): Invalid use of group function 

mysql> SELECT 
    -> GROUP_CONCAT(
    ->  CONCAT_WS('|||', 0, 1, 
    ->    (SELECT GROUP_CONCAT(CONCAT_WS('|', 2, 3) SEPARATOR '||')) 
    ->    ) 
    ->   ) `test`; 
+-------------+ 
| test  | 
+-------------+ 
| 0|||1|||2|3 | 
+-------------+ 
1 row in set (0,00 sec) 

UPDATE

一種可能的選擇:

mysql> DROP TABLE IF EXISTS `parts`, `labor`, `kits`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `kits` (
    -> `id` int(11) NOT NULL AUTO_INCREMENT, 
    -> `kit_id` int(11) DEFAULT NULL, 
    -> `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    -> `name` varchar(45) DEFAULT NULL, 
    -> `description` varchar(150) DEFAULT NULL, 
    -> `quantity` varchar(45) DEFAULT NULL, 
    -> PRIMARY KEY (`id`), 
    -> UNIQUE KEY `id_UNIQUE` (`id`), 
    -> KEY `KIT` (`kit_id`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `labor` (
    -> `id` int(11) NOT NULL AUTO_INCREMENT, 
    -> `kit_id` int(11) DEFAULT NULL, 
    -> `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    -> `description` varchar(150) NOT NULL, 
    -> `hours` varchar(45) NOT NULL DEFAULT '0', 
    -> PRIMARY KEY (`id`), 
    -> UNIQUE KEY `id_UNIQUE` (`id`), 
    -> KEY `KIT` (`kit_id`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `parts` (
    -> `id` int(11) NOT NULL AUTO_INCREMENT, 
    -> `kit_id` int(11) DEFAULT NULL, 
    -> `is_quote` tinyint(4) NOT NULL DEFAULT '0', 
    -> `name` varchar(45) DEFAULT NULL, 
    -> `description` varchar(150) DEFAULT NULL, 
    -> `sale_price` varchar(45) DEFAULT '0.00', 
    -> `quantity` varchar(45) NOT NULL, 
    -> PRIMARY KEY (`id`), 
    -> UNIQUE KEY `id_UNIQUE` (`id`), 
    -> KEY `KIT` (`kit_id`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO `kits` 
    -> (`id`, 
    -> `kit_id`, 
    -> `is_quote`, 
    -> `name`, 
    -> `description`, 
    -> `quantity`) 
    -> VALUES 
    -> (1,0,0,"Main Kit", "Sample Description",1); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `kits` 
    -> (`id`, 
    -> `kit_id`, 
    -> `is_quote`, 
    -> `name`, 
    -> `description`, 
    -> `quantity`) 
    -> VALUES 
    -> (2,1,0,"Kit within kit", "Sample Description",1); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `parts` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `name`, 
    -> `description`, 
    -> `sale_price`, 
    -> `quantity`) 
    -> VALUES 
    -> (1,0,"First Kit Part", "Part description","23.5",1); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `parts` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `name`, 
    -> `description`, 
    -> `sale_price`, 
    -> `quantity`) 
    -> VALUES 
    -> (2,0,"Kit within kit part 1", "Sample Part Description","23.5",1); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `parts` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `name`, 
    -> `description`, 
    -> `sale_price`, 
    -> `quantity`) 
    -> VALUES 
    -> (2,0,"Kit within kit part 2", "Sample Part Description","23.5",1); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `labor` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `description`, 
    -> `hours`) 
    -> VALUES 
    -> (1,0,"First Kit labor","1.5"); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `labor` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `description`, 
    -> `hours`) 
    -> VALUES 
    -> (2,0,"Kit within kit labor 1","1.5"); 
Query OK, 1 row affected (0.00 sec) 

mysql> INSERT INTO `labor` 
    -> (`kit_id`, 
    -> `is_quote`, 
    -> `description`, 
    -> `hours`) 
    -> VALUES 
    -> (2,0,"Kit within kit labor 2","1.5"); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT kits.id, kits.is_quote, 
    ->  GROUP_CONCAT(
    ->   CONCAT_WS('|||', kits_table.id, kits_table.name, 
    ->    (SELECT GROUP_CONCAT(
    ->     CONCAT_WS('|', parts.id, parts.name) 
    ->    SEPARATOR '||') FROM parts WHERE parts.kit_id = kits_table.id), 
    ->    (SELECT GROUP_CONCAT(
    ->     CONCAT_WS('|', labor.id, labor.description) 
    ->    SEPARATOR '||') FROM labor WHERE labor.kit_id = kits_table.id) 
    ->  ) 
    ->  SEPARATOR '||||' 
    -> ) as kits, 
    ->  GROUP_CONCAT(CONCAT_WS('|', parts.id, parts.name) SEPARATOR '|||') as parts, 
    ->  GROUP_CONCAT(CONCAT_WS('|', labor.id, labor.description) SEPARATOR '|||') as labor 
    -> FROM kits 
    ->  LEFT JOIN kits as kits_table ON kits_table.kit_id = kits.id 
    ->  LEFT OUTER JOIN parts ON parts.kit_id = kits.id 
    ->  LEFT OUTER JOIN labor ON labor.kit_id = kits.id 
    -> WHERE kits.id = 1 
    -> GROUP BY kits.id\G 
*************************** 1. row *************************** 
     id: 1 
is_quote: 0 
    kits: 2|||Kit within kit|||2|Kit within kit part 1||3|Kit within kit part 2|||2|Kit within kit labor 1||3|Kit within kit labor 2 
    parts: 1|First Kit Part 
    labor: 1|First Kit labor 
1 row in set (0.00 sec) 

更新2

mysql> SELECT kits.id, kits.is_quote, 
    -> GROUP_CONCAT(DISTINCT 
    ->  CONCAT_WS('|||', kits_table.id, kits_table.name, 
    ->   (SELECT GROUP_CONCAT(DISTINCT 
    ->    CONCAT_WS('|', parts.id, parts.name) 
    ->   SEPARATOR '||') FROM parts WHERE parts.kit_id = kits_table.id), 
    ->   (SELECT GROUP_CONCAT(DISTINCT 
    ->    CONCAT_WS('|', labor.id, labor.description) 
    ->   SEPARATOR '||') FROM labor WHERE labor.kit_id = kits_table.id) 
    ->  ) 
    -> SEPARATOR '||||' 
    -> ) as kits, 
    -> GROUP_CONCAT(DISTINCT CONCAT_WS('|', parts.id, parts.name) SEPARATOR '|||') as parts, 
    -> GROUP_CONCAT(DISTINCT CONCAT_WS('|', labor.id, labor.description) SEPARATOR '|||') as labor 
    -> FROM kits 
    -> LEFT JOIN kits as kits_table ON kits_table.kit_id = kits.id 
    -> LEFT OUTER JOIN parts ON parts.kit_id = kits.id 
    -> LEFT OUTER JOIN labor ON labor.kit_id = kits.id 
    -> WHERE kits.id = 1 
    -> GROUP BY kits.id\G 
*************************** 1. row *************************** 
     id: 1 
is_quote: 0 
    kits: 2|||Kit within kit|||3|Kit within kit part 1||4|Kit within kit part 2|||3|Kit within kit labor 1||4|Kit within kit labor 2 
    parts: 1|First Kit Part 1|||2|First Kit Part 2 
    labor: 1|First Kit labor 1|||2|First Kit labor 2 
1 row in set (0,00 sec) 
+0

我試圖做兩個GROUP_CONCAT(SELECT語句)(返回「子查詢返回多於1行錯誤。)和SELECT GROUP_CONCAT(語句)(返回之前收到的相同的組錯誤。) – forrestmid

+0

這實際上很有趣,因爲2,3的靜態值在我的查詢中工作,但是當被數據庫中的值替換時,它給了我組的錯誤,所以這實際上允許group_concat中的group_concat,但我認爲有多個返回值會阻止查詢從工作中得到答案 – forrestmid

+0

@forrestmid:查看更新後的答案 – wchiquito

0

我認爲問題是選擇字段和字段組之間的差異。

這是在MySQL該組的語法BY子句

SELECT expression1, expression2, ... expression_n, 
     aggregate_function (expression) 
FROM tables 
[WHERE conditions] 
GROUP BY expression1, expression2, ... expression_n; 

也許你通過字段只kits.is_quote添加到組,如果concat_group被視爲集合函數

+0

你能澄清一下嗎?我正在使用GROUP_CONCAT函數,這就是我認爲錯誤引用的原因。刪除GROUP BY kits.id後,該函數返回相同的錯誤。 – forrestmid

+0

我猜是不可能使用group_concat嵌套,我正在尋找關於此的文檔,但我找到了。但我對這個團隊的領域數量的建議仍然存在。 –

+0

我認爲這是可能的,因爲這個人說他這樣做,但代碼對我來說沒有多大意義。 HTTPS://www.percona。com/blog/2013/10/22/the-power-of-mysql-group_concat/ – forrestmid

0

這是相當奇怪的命名策略 - 同時擁有名爲id A柱和一個桌子上稱爲kit_id列稱爲kits。所以,我不確定我是否有這個權利。所以不要介意,如果這是你認爲你在尋找或沒有;是以下有效查詢...

SELECT k.id 
    , k.name kit_name 
    , k.description kit_description 
    , k.quantity kit_quantity 
    , p.name part_name 
    , p.description part_description 
    , p.sale_price part_price 
    , p.quantity part_quantity 
    , l.description labor_description 
    , l.hours labor_hours 
    FROM kits k 
    LEFT 
    JOIN parts p 
    ON p.kit_id = k.id 
    LEFT 
    JOIN labor l 
    ON l.kit_id = k.id; 

+----+----------------+--------------------+--------------+---------------------+-------------------------+------------+---------------+----------------------+-------------+ 
| id | kit_name  | kit_description | kit_quantity | part_name   | part_description  | part_price | part_quantity | labor_description | labor_hours | 
+----+----------------+--------------------+--------------+---------------------+-------------------------+------------+---------------+----------------------+-------------+ 
| 1 | Main Kit  | Sample Description | 1   | First Kit Part  | Part description  | 23.5  | 1    | First Kit labor  | 1.5   | 
| 2 | Kit within kit | Sample Description | 1   | Kit within kit part | Sample Part Description | 23.5  | 1    | Kit within kit labor | 1.5   | 
+----+----------------+--------------------+--------------+---------------------+-------------------------+------------+---------------+----------------------+-------------+ 
2 rows in set (0.00 sec) 

??

+0

當您瞭解kit_id的用途時,命名策略並不奇怪。 kit_id允許零件,人工和工具包引用父工具包。父套件上的kit_id是0,或者是null,所以kit_id只允許我有6個表只有3個,並且當我不需要它時不使用kit_id。查詢是有效的,但所有的別名都會造成問題。此外,每個父組件上可以有2個或更多零件,人工或套件。因此,可能有5個部分,每個kit_id爲1,或者5個kit_id爲1的kit,每個kit_id爲5,每個kit_id都是kit_id。 – forrestmid

+0

只需重申,kit_id在每個工具包行上都與id完全分離。每個工具包行都有自己的唯一ID,如果碰巧是另一個工具包下的子工具包,那麼kid_id將被設置爲其父工具包的ID,但不會等於它自己的唯一ID。 – forrestmid

+0

因此,在套件表中,'kit_id'就是我們通常所說的'parent_id' – Strawberry

0

這是一個潛在的問題解決方案,所以它可能會幫助其他人。這個特定的查詢可以在2個SELECT語句中完成,但問題是要在1個SELECT語句中完成它,所以我不會將其標記爲答案。

如果想要獲得多個主要工具包,這肯定不是好事,因爲您必須對主要工具包列表提出一個請求,然後遍歷這些主要工具包的for循環進行查詢爲每個套件在主套件內獲取套件。非常低效。

當需要的套件ID = 1,則:

//Fetch the main kit. 
SELECT kits.id, kits.is_quote, 
GROUP_CONCAT(CONCAT_WS('|', parts.id, parts.name) SEPARATOR '|||') as parts, 
GROUP_CONCAT(CONCAT_WS('|', labor.id, labor.description) SEPARATOR '|||') as labor 
FROM kits 
LEFT OUTER JOIN parts ON parts.kit_id = kits.id 
LEFT OUTER JOIN labor ON labor.kit_id = kits.id 
WHERE kits.id = '1' 
GROUP BY kits.id; 

//Fetch an array of kits where kit_id = 1 
SELECT kits.id, kits.is_quote, 
GROUP_CONCAT(CONCAT_WS('|', parts.id, parts.name) SEPARATOR '|||') as parts, 
GROUP_CONCAT(CONCAT_WS('|', labor.id, labor.description) SEPARATOR '|||') as labor 
FROM kits 
LEFT OUTER JOIN parts ON parts.kit_id = kits.id 
LEFT OUTER JOIN labor ON labor.kit_id = kits.id 
WHERE kits.kit_id = '1' 
GROUP BY kits.id;