为什么这个SQL查询没有返回预期的结果?

时间:2018-04-30 19:29:09

标签: sql sql-server

我是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

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您的示例数据库架构当前没有办法将Port行与ServerName行相关联,因此您的PIVOT将返回每列的文字max()值。由于您只查看包含多行的一行数据,因此PIVOT只会返回每个max记录的实际FieldValue行。您需要添加另一行,该行对于将PortServer相关联的每个“分组”结果都是唯一的。

我还对查询设置了别名,以便您可以查看查询中不同数据点的来源。这可能有助于理解PIVOT的流程。

SQL Fiddle

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