我不确定如何做到这一点,但我必须选择给定行中的所有列,其中值等于布尔值TRUE。
即
Columns: | X | Y | Z | A |
0 | TRUE | FALSE | TRUE | TRUE |
在这种情况下,我需要一个返回的SQL语句:
Columns: | X | Z | A |
0 | TRUE | TRUE | TRUE |
我在一个表中执行此操作,该表的大小不会发生变化(基本上是静态的),大约有250列和220行。
最终,我将需要一个语句,它返回TRUE的列名,基本上是:
0 | X | Z | A |
非常感谢任何帮助!
编辑1
根据下面的Nicarus解决方案,我想出了以下内容:
WITH i (A, B, C)
AS (
SELECT attributes.A, B, C
FROM (attributes JOIN contexts ON attributes.A = contexts.A)
WHERE context_full_name = 'Print book'
),
i_sub AS (
SELECT
A,
UNNEST(ARRAY['B', 'C'])
AS col_name,
UNNEST(ARRAY[B, C])
AS col_value
FROM i)
SELECT STRING_AGG(col_name, ',') AS true_col_names INTO temporary_table
FROM i_sub WHERE col_value = TRUE GROUP BY A;
SELECT * FROM temporary_table;
但是,我返回的结果是最终的select语句错误...
我使用以下方式进行了双重检查:
SELECT *
FROM (attributes JOIN contexts ON attributes.attribute_id = contexts.attribute_id)
WHERE context_full_name = 'Print book';
这个专栏肯定是假的......
我弄乱了什么吗?
编辑2
因此,EDIT 1中的查询试图实现以下目标;改变这个:
Columns: | X | Y | Z | A |
0 | TRUE | FALSE | TRUE | TRUE |
1 | TRUE | TRUE | TRUE | FALSE|
2 | FALSE| FALSE | TRUE | FALSE|
在这种情况下,我需要一个返回的SQL语句:
Columns: | X | Z | A |
0 | TRUE | TRUE | TRUE |
相反,它会返回所有具有真值的列:
Columns: | X | Y | Z | A |
0 | TRUE | TRUE | TRUE | TRUE |
我的实施
这绝不是最有效率的,但它对我想要实现的目标起作用:
SELECT attributes.attribute_id, context_full_name, A, B, C, D
INTO TEMP j
FROM (attributes JOIN contexts ON attributes.attribute_id = contexts.attribute_id)
WHERE contexts.context_full_name = 'Print book' LIMIT 1;
WITH i_sub AS (
SELECT
attribute_id,
context_full_name,
UNNEST(ARRAY[A, B, C, D]) AS col_value
FROM j)
SELECT ROW_NUMBER() OVER () as rn, *
INTO TEMP temporary_table
FROM i_sub;
SELECT context_full_name, attribute_id, temporary_table.rn, temporary_table.col_value, attribute_titles.attribute_name_column, attribute_titles.attribute_names
INTO TEMP result
FROM
(temporary_table JOIN attribute_titles -- attribute titles is a table I created which lists the column headers in the same order as they are in the attributes table, so that the row number on the temporary_table equals the attribute_titles column "attribute_name_id".
ON temporary_table.rn = attribute_titles.attribute_name_id) WHERE col_value = TRUE;
SELECT * FROM result; -- This prints the list with the attribute_id, context_full_name, the column value where TRUE (to check to make sure it worked), the column names shown in attribute_titles, and the attribute names (plaintext versions). This table can be further manipulated as necessary.
答案 0 :(得分:1)
我不是100%肯定你的用例;但是,您可以返回其值为TRUE
的列名称的“列表”。这只是一种方法。
这里我“解锁”数据,过滤掉任何FALSE
条记录,然后连接列名称以返回每行一条记录。您也可以决定使数据更规范化(不连接列名)
WITH mytable (row_id,X,Y,Z,A) AS
(
VALUES
(1,TRUE,TRUE,TRUE,FALSE),
(2,TRUE,FALSE,TRUE,FALSE),
(3,FALSE,TRUE,TRUE,TRUE)
),
mycte AS
(
SELECT
row_id,
UNNEST(ARRAY['X','Y','Z','A']) AS col_name,
UNNEST(ARRAY[X,Y,Z,A]) AS col_value
FROM
mytable
)
SELECT
row_id,
STRING_AGG(col_name,'|') AS true_col_names
FROM
mycte
WHERE
col_value
GROUP BY
row_id;
你说你仍然有问题,但我不清楚它们是什么。
我使用了您的查询(使用我的测试数据),我得到了这个:
DROP TABLE IF EXISTS temporary_table;
WITH i (A,B,C) AS
(
VALUES
(TRUE,TRUE,FALSE),
(FALSE,TRUE,FALSE),
(TRUE,TRUE,TRUE)
),
i_sub AS (
SELECT
A,
UNNEST(ARRAY['B', 'C'])
AS col_name,
UNNEST(ARRAY[B, C])
AS col_value
FROM i)
SELECT
STRING_AGG(col_name, ',') AS true_col_names,
STRING_AGG(DISTINCT col_name, ',') AS true_col_names_unique --only unique col_names
INTO
temporary_table
FROM
i_sub
WHERE
col_value;
SELECT * FROM temporary_table;
输出: