5

试图找到一种方法将 CONCAT 与 IF 结合起来——或以其他方式在逗号分隔列表中显示设置标志的文本值。

注意:这最终适用于具有 10 列以上的表。在这里使用两个来简化。

假设我有一张带旗帜的桌子。如果标志是1我想显示一些文本值,否则什么都没有。

origin:
+--+-----+-----+
|# | CHS | ACC |
+--+-----+-----+
|1 | 0   | 1   |
|2 | 1   | 1   |
|3 | 1   | 0   |
|4 | 0   | 0   |
+--+-----+-----+

我想:

+--+----------+
|# |  origin  |
+--+----------+
|1 | ACC      |
|2 | CHS, ACC |
|3 | CHS      |
|4 |          |
+--+----------+

不是(这个或类似的):

+--+-----------+
|# | origin    |
+--+-----------+
|1 | ACC,      |
|2 | CHS, ACC, |
|3 | CHS,      |
|4 | ,         |
+--+-----------+

朝着这个方向的东西:

SELECT
    CONCAT_WS(', ',
        IF(CHS = 0, '', 'CHS'),
        IF(ACC = 0, '', 'ACC')
    ) as origin
FROM
    origin;

但空值之间没有逗号。

这最终适用于一个包含 10 列的表,我根据 id 与其他表连接。

4

3 回答 3

5

您可以将 CONCAT_WS 与 CASE 结合使用,它会跳过 NULL 值:

SELECT
  id,
  CONCAT_WS(', ',
    CASE WHEN CHS THEN 'CHS' END,
    CASE WHEN ACC THEN 'ACC' END
  ) as origin
FROM
  origin;

当条件为 FALSE 时,由于我没有指定 ELSE 子句,因此 CASE 将返回 NULL 值,而 CONCAT_WS 将跳过它。您也可以在原始查询中使用 NULL 而不是 ''。

如果您有很多列,您还可以使用以下内容创建动态查询:

SELECT
  CONCAT(
    'SELECT ID, CONCAT_WS(\', \',',
    GROUP_CONCAT(
      CONCAT(
        'CASE WHEN ',
        `COLUMN_NAME`,
        ' THEN \'',
        `COLUMN_NAME`,
        '\' END') SEPARATOR ','),
    ') AS origin FROM origin;'
    )
FROM
  `INFORMATION_SCHEMA`.`COLUMNS` 
WHERE
  `TABLE_NAME`='origin'
  AND COLUMN_NAME!='id'
INTO @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;

在此处查看带有两种解决方案的小提琴。

于 2013-04-04T18:59:44.490 回答
3

可能有一个更好看的解决方案,但你可以使用

CONCAT(
    IF(CHS = 0, '', 'CHS'),
    IF(CHS != 0 AND ACC != 0, ', ', ''),
    IF(ACC = 0, '', 'ACC')
)

您还可以使用REPLACE删除“空白:”

REPLACE(CONCAT_WS(', ',
    IF(CHS = 0, 'REMOVEIT', 'CHS'),
    IF(ACC = 0, 'REMOVEIT', 'ACC')
), 'REMOVEIT, ', '')
于 2013-04-04T18:39:01.893 回答
1

试试这个。

SELECT
    TRIM(TRAILING ', ' FROM CONCAT_WS(', ',
        IF(CHS = 0, '', 'CHS'),
        IF(ACC = 0, '', 'ACC')
    )) as origin
FROM
    origin;

这是mysql文档。

http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_trim

于 2013-04-04T19:10:57.887 回答