有点不寻常的要求。我们有一个可以提出调查问题的软件。任何调查都可以包含任意数量的问题(很容易从 1 到 30 个问题,但没有限制)。
用户的请求是为每个调查、response_ID 和问题提取一行数据。我已经完成了这一点,因此数据的格式为:
调查ID | 响应_ID | 问题1 | 问题2... | 问题K | Q1 | Q2 |
---|---|---|---|---|---|---|
ABC | 1 | 1 | 空 | 空 | 空 | 空 |
ABC | 2 | 空 | 4 | 空 | 空 | 空 |
防御 | 1 | 空 | 空 | 空 | 10 | 空 |
GHI | 1 | 10 | 空 | 空 | ||
GHI | 2 | 空 | 5 | 空 |
哪里 调查 ABC 有 2 个问题,评分范围为 1-10 调查 DEF 有 1 个问题,但问题不标准,因此显示在 Q1 列中 调查 GHI 有 2 个问题,评分范围为 1-10
如果我们在 BI 工具中选择调查 DEF,我们不想显示列 QUestion1-QuestionK,我们只想要列 Q1 和 Q2
我想到的方法是按 Survey_ID 和 Response_ID 进行分组,但我们不知道有多少列,因此我们无法聚合其余列
按调查 ID 进行过滤,然后仅对这些结果创建一个临时表,并排除 Survey_ID、Response_ID 和合并(*) 作为所有列,然后仅显示带有数据的列,但这似乎返回所有列,因为我认为我需要首先聚合,然后仅包含有数据的列
期望的输出:在BI工具中 按调查 ID 筛选:
DEF
调查 | 回应 | Q1 |
---|---|---|
防御 | 1 | 10 |
筛选调查 ID:
ABC
调查ID | 回应 | 问题1 | 问题2 |
---|---|---|---|
ABC | 2 | 1 | 4 |
筛选:
GHI
调查ID | 回应 | 问题1 | 问题2 |
---|---|---|---|
GHI | 2 | 10 | 5 |
任何有关聚合、删除空列等的帮助将不胜感激。
select survey_ID, Response_ID, max(\*)
from surveypivot
Where survey_ID = 'DEF'
group by Survey_ID,Response_ID
免责声明:基于过滤器动态生成列列表是一个奇怪的请求,我个人不建议使用此类代码。
话虽如此,Snowflake SQL 的表达能力足以生成这样的输出:
WITH cte AS (
SELECT *, OBJECT_CONSTRUCT(* EXCLUDE (SURVEY_ID, RESPONSE_ID)) AS obj
FROM tab
WHERE Survey_ID = 'GHI'
) ,cte_unpivot AS (
SELECT SURVEY_ID, COUNT(*) OVER() AS RESPONSES, KEY, MAX(VALUE)::NUMBER AS VALUE
FROM cte
,TABLE(FLATTEN(obj))
GROUP BY SURVEY_ID, KEY
)
SELECT *
FROM cte_unpivot
PIVOT (MAX(VALUE) FOR KEY IN (ANY));
示例数据:
CREATE OR REPLACE TABLE tab(Survey_ID TEXT, Response_ID INT,Question1 INT, Question2 INT, QuestionK INT,Q1 INT, Q2 INT)
AS SELECT 'ABC',1 , 1,Null,Null, NULL,NULL
UNION SELECT 'ABC', 2, Null,4,NULL,NULL,NULL
UNION SELECT 'DEF', 1, Null ,Null, NULL,10 ,NULL
UNION SELECT 'GHI' ,1, 10, NULL, NULL, NULL, NULL
UNION SELECT 'GHI',NULL, 2, NULL, 5, NULL, NULL;
输出: