如何查询 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 表的主要内容,如果未能解决你的问题,请参考以下文章