[英]Mysql group_concat limit rows in grouping
下一个例子是我的数据库。
tb_port id port 1 80 2 22 3 53 4 3128 5 443
tb_dest id dest 1 network 2 local
tb_rule id id_port id_dest 1 1 1 2 2 1 3 3 1 4 4 1 5 5 1
选择: select dest,group_concat(port) from tb_port a, tb_dest b, tb_rule c where a.id=c.id_port and b.id=c.id_dest group by dest
结果: network 80,22,53,3128,443
但不是我要找的结果,结果就是这个。
选择ex:从tb_port a,tb_dest b,tb_rule c中选择dest,group_concat(端口限制2),其中a.id = c.id_port和b.id = c.id_dest group by dest
结果我想
network 80,22 network 53,3128 network 443
如何只用SQL实现这个结果?
Sqlfiddle: http ://sqlfiddle.com/#!2 / d11807
MySQL不会使这种查询变得容易,但是一个(当然不是很漂亮)解决方案是使用变量为每个每行提供一个序列号,并按行号整数除以2得到两个数字每组;
SELECT dest, GROUP_CONCAT(port ORDER BY rank) ports
FROM (
SELECT dest, port, (
CASE dest WHEN @curDest
THEN @curRow := @curRow + 1
ELSE @curRow := 1 AND @curDest := dest END) rank
FROM tb_port a
JOIN tb_rule c ON a.id = c.id_port
JOIN tb_dest b ON b.id = c.id_dest,
(SELECT @curRow := 0, @curDest := '') r
ORDER BY dest
) z
GROUP BY FLOOR(rank/2),dest
ORDER BY dest, MIN(rank)
这是一个存储过程,你只需在调用时放入分隔符
DELIMITER $$
DROP PROCEDURE IF EXISTS explode_table $$
CREATE PROCEDURE explode_table(bound VARCHAR(255))
BEGIN
DECLARE id TEXT;
DECLARE value TEXT;
DECLARE occurance INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE splitted_value TEXT;
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR
select dest,group_concat(port) from tb_port a, tb_dest b, tb_rule c
where a.id=c.id_port and b.id=c.id_dest and dest != '' group by dest;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS table2;
CREATE TEMPORARY TABLE table2(
`id` VARCHAR(255),
`value` VARCHAR(255) NOT NULL
) ENGINE=Memory;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO id, value;
IF done THEN
LEAVE read_loop;
END IF;
SET occurance = (SELECT LENGTH(CONCAT(value,bound))
- LENGTH(REPLACE(CONCAT(value,bound), bound, ''))
+1);
SET i=2;
WHILE i <= occurance DO
SET splitted_value =
SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(value,bound),bound,i),bound,-2) ;
INSERT INTO table2 VALUES (id, splitted_value);
SET i = i + 2;
END WHILE;
END LOOP;
SELECT * FROM table2;
CLOSE cur1;
END; $$
CALL explode_table(',')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.