如何查询 SQL 表

Posted

技术标签:

【中文标题】如何查询 SQL 表【英文标题】:How to query a SQL table 【发布时间】:2021-07-29 22:36:17 【问题描述】:

我有一个看起来像这样的表:

IDPerson Name Type Value
D601108B-8A37-4BD2-BB6F-0012A11BD929 FirstName NULL Bernard
D601108B-8A37-4BD2-BB6F-0012A11BD929 InternalNumber NULL Emp-001
D601108B-8A37-4BD2-BB6F-0012A11BD929 Name NULL Fish
D601108B-8A37-4BD2-BB6F-0012A11BD929 ValidFrom System.DateTime 10/20/2020 00:00:00
D601108B-8A37-4BD2-BB6F-0012A11BD929 ValidTo System.DateTime 10/31/2025 00:00:00

我的问题是如何编写查询以将所有这些信息提取到一个表中,该表基本上具有“名称”列中的列标题,即 FirstName 等,以便我有一行用于所有与伯纳德?

【问题讨论】:

您应该使用您正在使用的数据库供应商标记您的问题。一般推荐用于任何 SQL 问题,尤其是在您的问题中。您要寻找的通常称为旋转。一些供应商提供方便的语法支持。或者,您可以将查询组合为每一列的子选择。 这能回答你的问题吗? SQL query to pivot a column using CASE WHEN 【参考方案1】:

如果您使用的是 MS SQL Server(从 .NET System.DateTime 猜测),则可以使用 pivot 子句:

with t (id,c,t,v) as (
select 'D601108B-8A37-4BD2-BB6F-0012A11BD929','FirstName'   ,NULL   ,'Bernard' union all
select 'D601108B-8A37-4BD2-BB6F-0012A11BD929','InternalNumber' ,NULL    ,'Emp-00' union all
select 'D601108B-8A37-4BD2-BB6F-0012A11BD929','Name'    ,        NULL   ,'Fish' union all
select 'D601108B-8A37-4BD2-BB6F-0012A11BD929','ValidFrom'   ,'System.DateTime'  ,'10/20/2020 00:00:00' union all
select 'D601108B-8A37-4BD2-BB6F-0012A11BD929','ValidTo'     ,'System.DateTime'  ,'10/31/2025 00:00:00'
)
select *
from (select c,v from t) as s
pivot (max(v) for c in ([FirstName], [InternalNumber], [Name], [ValidFrom], [ValidTo])) as p

(db fiddle)

Oracle 的原则相同,语法不同。

在纯 SQL 中,您可以使用重复问题候选中所述的用例(与此问题不同,该问题使用数字运算,因此恕我直言,它不是明确的重复 - 使用忽略空值的 max 函数):

with t (id,c,t,v) as (values
('D601108B-8A37-4BD2-BB6F-0012A11BD929','FirstName'     ,NULL   ,'Bernard'),
('D601108B-8A37-4BD2-BB6F-0012A11BD929','InternalNumber' ,NULL  ,'Emp-00'),
('D601108B-8A37-4BD2-BB6F-0012A11BD929','Name'  ,        NULL   ,'Fish'),
('D601108B-8A37-4BD2-BB6F-0012A11BD929','ValidFrom'     ,'System.DateTime'  ,'10/20/2020 00:00:00'),
('D601108B-8A37-4BD2-BB6F-0012A11BD929','ValidTo'   ,'System.DateTime'  ,'10/31/2025 00:00:00')
)
select max(case when c='FirstName' then v end)
     , max(case when c='InternalNumber' then v end)
     -- etc
from t
group by t.id

(db fiddle)

在 Postgres 中,可以使用 max(v) filter (where c='FirstName') 子句对其进行简化。或交叉表扩展。

【讨论】:

以上是关于如何查询 SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

sql如何一对多联合查询

sql中引用一个表的查询结果作为条件来查询另一个表如何实现?

mysql 如何使用sql查询某一个表的表头

sql mysql多表如何关联查询

sql如何在多个表中查询一个表的全部列

如何在包含其他几个查询的 sql 查询中对表进行连接?