sql - 交叉表查询提供了意外的结果

标签 sql postgresql crosstab

我对 PostgreSQL 的 tablefunc 扩展中的 crosstab() 函数有点困惑。问题是我想要的不是标准的Name-Category-Value 方案,而是类似Name-Attribute of Name-One more attribute-Category-Value 之类的东西。这似乎不是问题,但很快我就意识到,使用我的数据库方案并不像我想象的那么容易。

背景:我有 3 个表要使用:UsersUserEventsQuestionaryAnswers

  1. Users 表包含人
  2. UserEvents 包含此人发生的事件(FK 引用用户)
  3. 和 QuestionaryAnswers,其中包含通过 FK 引用 UserEventId 的问题的答案。

所以,表格看起来像这样:

create table "Users"("Id" int, "AttrId" int, "GroupId" int);
create table "UserEvents"("Id" int, "UserId" int, "Status" varchar(20), "EventId" int);
create table "QuestionaryAnswers"("UserEventId" int, "QuestionaryItemId" int, "AnswerItemId" int);

用户:

INSERT INTO "public"."Users"("Id", "AttrId", "GroupId") 
VALUES (1, 1, 12587), (2, 1, 11092);

用户事件:

INSERT INTO "public"."UserEvents"("Id", "UserId", "Status", "EventId") 
VALUES (142, 1, 'Checked', 2), (143, 1, 'Created', 1), (144, 2, 'Done', 2);

和问题答案:

INSERT INTO "public"."QuestionaryAnswers"("UserEventId", "QuestionaryItemId", "AnswerItemId") 
VALUES ('142', 1, 2),
('142', 4, 16),
('142', 5, 25),
('143', 12, 99);
('144', 12, 100);

嗯,这就是出现问题的地方。这是我现在的交叉表查询:

SELECT *
FROM crosstab(' SELECT "UserEvents"."UserId", "QuestionaryAnswers"."UserEventId", "Users"."AttrId", "Users"."GroupId", "QuestionaryAnswers"."QuestionaryItemId", "AnswerItems"."Name"
 FROM "QuestionaryAnswers"
    LEFT JOIN "AnswerItems" ON "QuestionaryAnswers"."AnswerItemId" = "AnswerItems"."Id" 
    LEFT JOIN "UserEvent" ON "QuestionaryAnswers"."UserEventId" = "UserEvents"."Id" 
    LEFT JOIN "Users" ON "UserEvents"."UserId" = "Users"."Id"
    ORDER BY 1, 2'::text, 
'SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 UNION SELECT 13 UNION SELECT 14 UNION SELECT 15 UNION SELECT 16 UNION SELECT 17 UNION SELECT 18 UNION SELECT 20 UNION SELECT 21 ORDER BY 1'::text) 
crosstab("UserId" integer, "UserEventId" uuid,
"AttrId" integer, "GroupId" integer,
"Question1" text, "2" text, "3" text, "4" text,
"5" text, "6" text, "7" text, "8" text, "9" text,
"10" text, "11" text, "12" text, "13" text, "14" text,
"15" text, "16" text, "17" text, "18" text, "19" text)

这里一切看起来都很简单,除了一个小细节 - 类别\列\问题链接到不同的 UserEventId,所以基本上 UserEventId 是随机选择的(通过 ORDER 子句),并且由于UserEvents 表中的 Status 属性也将被随机选取。我想看到的是由 EventId 派生的单独的 UserEventId 和 Status 字段,因此会有 UserEventId_1UserEventId_2 ID,并且可能链接字段,例如 Status_1Status_2,如下所示:

UserId | UserEventId_EventId1 | UserEventId_EventId2 | AttrId | GroupId | Question1 | Question3 | Question4 | Question5 | Question12
-------+----------------------+----------------------+--------+---------+-----------+-----------+-----------+-----------+-----------
     1 |                  143 |                  142 |      1 |   12587 |           |           |        16 |        25 |         99
     2 |                      |                  144 |      1 |   11092 |           |           |           |           |        144

所以问题是:

  1. 如何根据外键值制作“类别”交叉表列?我无法弄清楚,可能是因为它是不同类别的“堆栈”- 事件和问题。
  2. 整个想法有点错误 - 交叉表并不是为了以我想要的格式显示数据,所以我将描述目标。我需要一个表来运行简单的比较查询“有多少人这样回答问题 1 并回答这样的问题 2”,但我还需要在“UserEvents”Status 字段和“Users”GroupId 字段,因此我需要表中的 EventID 或 Status。我是否错过了一些更简单的机会或一些在交叉表中显示此数据的能力? P.S 我正在使用 PostgreSQL 11.1

最佳答案

到目前为止,您所描述的可以在没有交叉表调用的情况下实现:

select u1."Id" as "UserId", u1."GroupId", e1."Status", 
    q1."QuestionaryItemId", q1."AnswerItemId", count(*)
from "Users" u1
left join "UserEvents" e1
on u1."Id" = e1."UserId"
left join "QuestionaryAnswers" q1
on q1."UserEventId"=e1."Id"
group by 1,2,3,4,5

您可以查看结果here .

关于sql - 交叉表查询提供了意外的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53885739/

相关文章:

ruby-on-rails - gem rinruby 的 RubyOnRails 错误

具有两个交叉表和多个列的 SQL 数据透视表

sql - PostgreSQL "nested"?区分和计数

sql - PostgreSQL:没有函数匹配给定的名称和参数类型

sql - 在 WHERE 有 OR 条件的情况下组合多个索引

postgresql - 在 redshift postgresql 中,我可以使用复制功能跳过列吗

postgresql - Postgres :\copy syntax error in . sql文件

python - 比较字典的值并返回匹配值的计数

sql - 与两个或多个字段/变量上的SELECT DISTINCT等效

java - 在Android屏幕方向更改上重绘SQL中的多段线