有3张桌子

Table User

user_id created_at
1001 2022-10-01
1002 2022-10-02
1003 2022-10-03
1004 2022-10-04
1005 2022-10-05

Table Default_Properties

def_id type value
10 type_a val_a
11 type_b val_b
12 type_c val_c
13 type_d val_d
14 type_e val_e

Table Custom_Properties

pro_id fk_user_id type value
20 1002 type_b banana
21 1005 type_d durian

默认情况下,每个用户都将拥有默认属性,除非用自定义属性覆盖.因此,预期结果如下:

Expected Result

user_id type_a type_b type_c type_d type_e
1001 val_a val_b val_c val_d val_e
1002 val_a banana val_c val_d val_e
1003 val_a val_b val_c val_d val_e
1004 val_a val_b val_c val_d val_e
1005 val_a val_b val_c durian val_e

我试着用"Case When"来转移话题,但没能得到预期的结果.非常感谢您提供的任何查询帮助/建议.谢谢!

推荐答案

SELECT u.user_id,
  MAX(CASE d.type WHEN 'type_a' THEN COALESCE(c.value, d.value) END) AS type_a,
  MAX(CASE d.type WHEN 'type_b' THEN COALESCE(c.value, d.value) END) AS type_b,
  MAX(CASE d.type WHEN 'type_c' THEN COALESCE(c.value, d.value) END) AS type_c,
  MAX(CASE d.type WHEN 'type_d' THEN COALESCE(c.value, d.value) END) AS type_d,
  MAX(CASE d.type WHEN 'type_e' THEN COALESCE(c.value, d.value) END) AS type_e
FROM user AS u
CROSS JOIN Default_Properties AS d 
LEFT OUTER JOIN Custom_Properties AS c ON u.user_id=c.fk_user_id AND c.type=d.type
GROUP BY u.user_id
ORDER BY u.user_id;

在MySQL 8.0.29上测试的输出:

+---------+--------+--------+--------+--------+--------+
| user_id | type_a | type_b | type_c | type_d | type_e |
+---------+--------+--------+--------+--------+--------+
|    1001 | val_a  | val_b  | val_c  | val_d  | val_e  |
|    1002 | val_a  | banana | val_c  | val_d  | val_e  |
|    1003 | val_a  | val_b  | val_c  | val_d  | val_e  |
|    1004 | val_a  | val_b  | val_c  | val_d  | val_e  |
|    1005 | val_a  | val_b  | val_c  | durian | val_e  |
+---------+--------+--------+--------+--------+--------+

在SQL中不可能实现"动态列".

在分析查询时,即在读取表中的任何数据之前,列必须是固定的.因此,除了您在编写查询时在SELECT-LIST中显式指定的列之外,查询在读取数据时无法展开列.

以此类推,这就像是调用一个Java函数,其名称是该函数的返回值.

因此,要创建有效的透视表,如果要为其创建列的属性可能会更改,则必须按两个步骤执行查询:首先,知道要为其创建列的属性集.类似以下内容将为您提供属性列表:

SELECT DISTINCT type FROM Default_Properties
UNION
SELECT DISTINCT type FROM Custom_Properties;

然后使用该查询的结果构建您的数据透视表查询.(即代码循环,将表达式作为字符串附加到查询的 Select 列表中.)

Mysql相关问答推荐

是否有一种方法可以 Select 表中具有特定列值的行,该行还显示phpmyadmin中原始表中的行号?

如何重新采样SQL数据库

如何将MySQL与AS&Quot;语法一起用于存储过程返回的表?

在MySQL中查找具有公共值的列名

MySQL连接序列

使用MySQL工作台导出具有数据的数据库表并导入到其字段具有不同数据类型的同一表中

了解MySQL_stmt_BIND_NAMED_Param()-MySQL C API

MySQL全文索引和不区分大小写搜索带来的挑战

计算符合字段值只能包含一种事件类型这一事实的记录

如何对 varchar() 数据值使用聚合窗口函数?

Group By 查询运行速度太慢而无法正常运行

Mysql时间序列数据的最小值和最大值

在表中找到最大值,然后分别显示SQL组和每个SQL组中的最大值计数

MySQL如何在小时和分钟之间 Select 时间

将 wordpress 自定义字段转换为单个数组

如何在不违反唯一约束的情况下交换 MySQL 中两行的值?

如何在mysql中连接整数(整数和整数)和varchar(nvarchar和varchar)等数据类型?

从mysql中的大表中快速 Select 随机行

警告:mysqli_connect(): (HY000/1045): Access denied for user 'username'@'localhost' (using password: YES)

在 Ubuntu 上安装 mysql gem 的困难