【发布时间】:2016-08-04 01:40:35
【问题描述】:
我不确定如何执行此操作,但我必须选择给定行中值等于布尔值 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 *
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.
【问题讨论】:
-
同一列中的
TRUE和FALSE值是否对所有行都相同?意思是,对于所有行,X始终为TRUE或始终为FALSE? -
不,他们并不抱歉。虽然我一次只使用一行,所以我可以创建一个只有一行的临时子表? (这样子表中的所有行都相同?)
-
您没有选择列。您选择行。匹配行中的列然后被投影。因此,在这种情况下,这意味着由于每一行可能具有不同的真/假列值组合组合,因此每一行在结果集中将具有不同的结构。那不可能发生。结果集是一个表结构。按列行。查询结果集中的每一行不能有不同的列。
标签: sql database postgresql