【问题标题】:Mysql, exchange comma separated values by internal select with where clauseMysql,通过内部选择与where子句交换逗号分隔值
【发布时间】:2017-01-26 08:44:54
【问题描述】:

我有 2 张桌子:

tab1(值与 tab2 有逗号分隔的 id):

id1   val1
-----------
1      1
2     1,2
3     1,3

标签2:

id2   val2
-----------
1      a
2      b
3      c

我想列出 Tab1 中的值并将逗号分隔的 val1 替换为 val2

我做了这样的事情:

SELECT *, (SELECT GROUP_CONCAT(val2) FROM tab2 WHERE id2 IN val1 ) from tab1

但它会在 tab1 的 'val1 ) 附近生成语法错误

当我删除 Where 子句时,它可以完美运行:

SELECT *, (SELECT GROUP_CONCAT(val2) FROM tab2) from tab1

它会产生:

id1   val1  (SELECT GROUP_CONCAT(val2) FROM tab2 )
1     1,2      a,b,c
2     1,3      a,b,c

但我想在第三行有与 Val1 数字相对应的字母(只有 a、b 和 a、c)。关键是将 Tab1.val1: 1,2... 中的数字替换为 tab2.val2 中的字母。它应该产生:

id1   val1  (SELECT GROUP_CONCAT(val2) FROM tab2 WHERE id2 IN val1)
1     1,2      a,b
2     1,3      a,c

当我添加 where 子句时发生了一些事情,但我找不到我的错误。

也许有其他想法可以用其他表中的字母值替换这个逗号分隔的数字?

【问题讨论】:

  • 好的,那你要生产什么?
  • 我希望第一行只有 a,b,第二行只有 a,c
  • val1 中最多有 2 个值?它们能有多大?
  • 没有。第三列应该对应于第二列,但将 1,2 替换为 tab2 中的字母。如果 Val1= 1,1,2,2,3,3,3,3 那么在第三列应该出现:a,a,b,b,c,c,c,c

标签: mysql comma group-concat


【解决方案1】:

你可以使用FIND_IN_SET()函数:

SELECT *, (SELECT GROUP_CONCAT(val2) FROM `tab2` WHERE FIND_IN_SET(id2,val1) > 0 ) as val2_tab2 FROM `tab1` ;

这是一个小提琴:http://rextester.com/ZMFML52150

【讨论】:

  • 这太棒了!非常感谢:)
【解决方案2】:

如果你可以创建一个函数,这可能会做

drop function if exists `F`;
delimiter //

CREATE DEFINER=`root`@`localhost` FUNCTION `F`(
    `instring` varchar(255)
)
RETURNS varchar(255) CHARSET latin1
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
begin
declare   tempstring varchar(100);
declare   outstring  varchar(100);
declare  val2string varchar(100);
declare  checkit int;
set tempstring = ltrim(rtrim(instring));
set checkit = 0;
set val2string = '';
looper: while   tempstring is not null and instr(tempstring,',') > 0 do
        set outstring = substr(tempstring,1,instr(tempstring, ',') - 1);
        set tempstring = substr(tempstring,instr(tempstring, ',') + 1,length(tempstring) - instr(tempstring, ',') + 1);
        set checkit = 1 ;
        set val2string = concat(val2string,(select val2 from tab2 where id = outstring),',');
end while; 


if checkit = 0 then 
    set val2string = 'Comma not found-no val2'; 
else
    set val2string = concat(val2string,(select val2 from tab2 where id = tempstring));
end if;
return val2string;
end //

delimiter ;

ariaDB [sandbox]> drop table if exists tab1;
Query OK, 0 rows affected (0.09 sec)

MariaDB [sandbox]> drop table if exists tab2;
Query OK, 0 rows affected (0.08 sec)

MariaDB [sandbox]> create table tab1(id int,  val1 varchar(20));
Query OK, 0 rows affected (0.22 sec)

MariaDB [sandbox]> insert into tab1 values
    -> (1  ,    '1'),
    -> (2  ,   '1,2'),
    -> (3  ,   '1,3'),
    -> (4  ,   '1,1,2,2,3,3,3,3');
Query OK, 4 rows affected (0.05 sec)
Records: 4  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> create table tab2(id int,  val2 varchar(20));
Query OK, 0 rows affected (0.30 sec)

MariaDB [sandbox]> insert into tab2 values
    -> (1 ,     'a'),
    -> (2 ,     'b'),
    -> (3 ,     'c');
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> SELECT ID,`F`(VAL1) FROM TAB1;
+------+-------------------------+
| ID   | `F`(VAL1)               |
+------+-------------------------+
|    1 | Comma not found-no val2 |
|    2 | a,b                     |
|    3 | a,c                     |
|    4 | a,a,b,b,c,c,c,c         |
+------+-------------------------+
4 rows in set (0.00 sec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2012-05-15
    • 2020-12-16
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多