【问题标题】:Select column names that match a criteria (MySQL)选择符合条件的列名 (MySQL)
【发布时间】:2013-04-17 15:18:38
【问题描述】:

我的数据库中有以下结构:

id,col_a,col_b,col_c,etc...

现在,除了 id 之外的所有其他列都是布尔类型。比如说

col_a=1,
col_b=0,
col_c=1

我正在寻找一种方法来返回列为真 (=1) 的列的名称,因此在此示例中,返回应该类似于 col_a,col_c

会有动态数量的列,因为表经常被更改以添加新列并删除旧列。

到目前为止我的函数看起来像这样 - 它是应该返回列名字符串的函数......

DROP FUNCTION fn_access;

DELIMITER //;

CREATE FUNCTION fn_access (myid INT) RETURNS varchar(800)
   DETERMINISTIC
BEGIN
            DECLARE ret_val VARCHAR(800);
            DECLARE col_name VARCHAR(255);
            DECLARE i INT;
            DECLARE num_rows INT;

            DECLARE col_names CURSOR FOR

            SELECT column_name
            FROM information_schema.columns
            WHERE `table_name` = 'access' AND `table_schema` = 'some_db' AND `column_name` <> 'id'
            ORDER BY ordinal_position;

            SELECT FOUND_ROWS() into num_rows;

            SET i = 1;
            the_loop: LOOP

            IF i > num_rows THEN
                            CLOSE col_names;
                            LEAVE the_loop;
            END IF;


            FETCH col_names 
            INTO col_name;

            SET ret_val = CONCAT(',' col_name);

            SET i = i + 1;  
            END LOOP the_loop;      

            SELECT * FROM access WHERE id = @myid;

            RETURN ret_val;
END
//

有没有办法使用直接 SQL 来做到这一点?我正在使用 MySQL。

【问题讨论】:

  • 列为真的列???您的意思是列本身或相应的行值
  • 是的,行值。所以换句话说,我想要col_a 如果col_a = 1col_b 如果col_b = 1 等等。

标签: mysql sql


【解决方案1】:

如果我正确理解你的问题,也许你需要这样的东西:

SELECT 'col_a' col
FROM yourtable
WHERE col_a
UNION
SELECT 'col_b'
FROM yourtable
WHERE col_b
UNION
SELECT 'col_c'
FROM yourtable
WHERE col_c
...

这将返回表格中至少有一行为真的所有列。

或者这样:

SELECT
  id,
  CONCAT_WS(', ',
    CASE WHEN col_a THEN 'col_a' END,
    CASE WHEN col_b THEN 'col_b' END,
    CASE WHEN col_c THEN 'col_c' END) cols
FROM
  yourtable

将以这种格式返回行:

| ID | COLS                |
----------------------------
|  1 | col_a, col_c        |
|  2 | col_a, col_b, col_c |
|  3 |                     |
|  4 | col_c               |
...

请看小提琴here。如果你需要动态地做,你可以使用这个准备好的语句:

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

PREPARE stmt FROM @sql;
EXECUTE stmt;

小提琴here

【讨论】:

  • 感谢您的回答,我现在就实现它。但这并不能满足 200 种不同的 col 的需求?这可以工作,但这并不能解决表列不断变化的问题。有没有一种方法可以遍历表中的所有列并在所有列上执行此操作?
  • @user1795229 我已经更新了我的答案,我添加了一种动态创建查询的方法,我希望没问题
  • 太棒了!这将非常有效。还有一个问题,我将如何将该连接的字符串返回到我上面编写的函数中?整个想法是使用上面的函数将连接的字符串取出以供以后使用。
  • @user1795229 tnx,而不是使用函数,我会准备一个参数化语句,然后用不同的 id 执行它,在这里看到它sqlfiddle.com/#!2/8f4ee/17 但如果你需要一个函数,请告诉我
  • 你所拥有的是辉煌,但不幸的是它必须与功能一起使用。这是因为该函数将用于其他 SQL 语句和第三方软件。我们必须能够将该字符串作为另一个查询的结果集的一部分返回。
猜你喜欢
  • 2013-07-19
  • 2019-09-05
  • 2012-10-24
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 2011-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多