4

私のDBには次の構造があります:

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

現在、id を除く他のすべての列はブール型です。たとえば、

col_a=1,
col_b=0,
col_c=1

列が true (=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を使用しています。

4

1 に答える 1

3

あなたの質問を正しく理解できれば、次のようなものが必要になるかもしれません。

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
...

これにより、少なくとも 1 つの行が true であるテーブル内のすべての列が返されます。

または多分これ:

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               |
...

ここでフィドルを参照してください。動的に実行する必要がある場合は、次の準備済みステートメントを使用できます。

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;

ここでフィドル。

于 2013-04-17T07:05:17.037 に答える