我是SQL Server的新手,我试图理解并知道为什么以下查询没有返回数据:
SELECT Port,Server
FROM (
SELECT FieldName,FieldValue
FROM tblConstants
WHERE FuncName='Mail' and IsActive=1) d
pivot (
max(FieldValue)
for FieldName in (Port,Server)
) piv;
包含接下来两行的查询的第一部分正常工作并返回所需的值:
SELECT FieldName,FieldValue
FROM tblConstants
WHERE FuncName='Mail' and IsActive=1
然而,在将这两行与第二部分组合后,查询不会返回任何值,我不知道为什么。
您能否向我解释为什么它不会返回数据?
更新: 期望的结果是:
Port --------------- Server
50 --------------- testserver.company.com
答案 0 :(得分:0)
这种情况正在发生,因为您的示例数据库架构当前没有办法将Port行与ServerName行相关联,因此您的PIVOT
将返回每列的文字max()
值。由于您只查看包含多行的一行数据,因此PIVOT
只会返回每个max
记录的实际FieldValue
行。您需要添加另一行,该行对于将Port
与Server
相关联的每个“分组”结果都是唯一的。
我还对查询设置了别名,以便您可以查看查询中不同数据点的来源。这可能有助于理解PIVOT
的流程。
MS SQL Server 2017架构设置:
CREATE TABLE tblConstants (
FieldName varchar(100)
, FieldValue varchar(100)
, FuncName varchar(100)
, isActive bit
, relatedField varchar(10));
/* Create "4" rows of data to PIVOT */
INSERT INTO tblConstants (FieldName, FieldValue, FuncName, isActive, relatedField)
VALUES
('Port', 'q','Mail',1, 'group1')
, ('Server','testserver.company.com','Mail',1, 'group1')
, ('Port', 'b','Mail',1, 'group2')
, ('Server','testserver2.company.com','Mail',1, 'group2')
, ('Port', 'd','Mail',1, 'group3')
, ('Server','testserver3.company.com','Mail',1, 'group3')
, ('Port', 'a','Mail',1, 'group4')
, ('Server','testserver4.company.com','Mail',1, 'group4')
;
基本查询:此查询是我们正在使用的基础数据。
SELECT
t.FieldName
, t.FieldValue
, t.relatedField /* This is our relation row */
FROM tblConstants t
WHERE t.FuncName='Mail' and t.IsActive=1
ORDER BY relatedField, FieldName, FieldValue
<强> Which Gives Us 强>:
| FieldName | FieldValue | relatedField |
|-----------|-------------------------|--------------|
| Port | q | group1 |
| Server | testserver.company.com | group1 |
| Port | b | group2 |
| Server | testserver2.company.com | group2 |
| Port | d | group3 |
| Server | testserver3.company.com | group3 |
| Port | a | group4 |
| Server | testserver4.company.com | group4 |
请注意,relatedField
会为每个相关FieldValue
组提供唯一的值。
完整的PIVOTed查询:
SELECT piv.Port, piv.Server
FROM (
SELECT
t.FieldName
, t.FieldValue
, t.relatedField /* This is our relation row */
FROM tblConstants t
WHERE t.FuncName='Mail' and t.IsActive=1
) d
pivot (
max(d.FieldValue)
for d.FieldName in (Server,Port)
) piv
<强> Final Results 强>:
| Port | Server |
|------|-------------------------|
| q | testserver.company.com |
| b | testserver2.company.com |
| d | testserver3.company.com |
| a | testserver4.company.com |
我们PIVOT
FieldName
,因为我们聚合,我们必须有一些东西可以将各个群体区分开来,以提供群组的有效聚合,即使我们不在最终输出中指定该列(如果需要,我们可以从SELECT
结果集中relatedGroup
piv
。