在SQL Server中按两列计算?

时间:2017-08-03 14:14:08

标签: sql sql-server

以下是一个示例表:

CREATE TABLE Example 
(
    LastName varchar(255),
    FirstName varchar(255),
    HomeAddress varchar(255),
    City varchar(255) 
);

INSERT INTO Example VALUES ('Murphy', 'James','123 Easy St', 'New York');
INSERT INTO Example VALUES ('Black', 'John','123 Easy St', 'Boston');
INSERT INTO Example VALUES ('Black', 'Amy','123 Easy St', 'Chicago');
INSERT INTO Example VALUES ('Simpson', 'Bill','123 Easy St', 'New York');
INSERT INTO Example VALUES ('Jones', 'James','123 Easy St', 'Chicago');
INSERT INTO Example VALUES ('Black', 'John','123 Easy St', 'Boston');
INSERT INTO Example VALUES ('Murhpy', 'James','123 Easy St', 'New York');

我希望能够计算两列,'LastName'和'City'。那是 - 我想要这个:

Name        New York  Boston  Chicago
-------------------------------------
Jones            0      0       1
Black            0      2       1
Simpson          1      0       0
Murphy           2      0       0

我的问题类似于this question。我创建了以下内容,它产生了非常接近的结果:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX),
        @PivotColumnNames AS NVARCHAR(MAX),
        @PivotSelectColumnNames AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column
SELECT @PivotColumnNames = ISNULL(@PivotColumnNames + ',','') + QUOTENAME(City)
FROM (SELECT DISTINCT City FROM Example) AS cat

--Get distinct values of the PIVOT Column with isnull
SELECT @PivotSelectColumnNames 
= ISNULL(@PivotSelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME(City) + ', 0) AS '
+ QUOTENAME(City)
FROM (SELECT DISTINCT City FROM Example) AS cat

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
N'SELECT LastName, ' + @PivotSelectColumnNames + '
FROM Example
pivot(count(City) for City in (' + @PivotColumnNames + ')) as pvt';

--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery

但是,这不是我所追求的。它产生了这个:

enter image description here

我尝试将“GROUP BY LastName”添加到查询的末尾,但它不起作用。我收到一个错误:

Column 'pvt.Boston' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

4 个答案:

答案 0 :(得分:3)

你真是太近了!

两件事:

  1. 使用子查询/派生表仅选择数据透视表所需的列
  2. 不要拼错墨菲
  3. --Prepare the PIVOT query using the dynamic 
    SET @DynamicPivotQuery = 
    N'SELECT LastName, ' + @PivotSelectColumnNames + '
    FROM (select LastName, City from Example) e
    pivot(count(City) for City in (' + @PivotColumnNames + ')) as pvt';
    

    rextester演示:http://rextester.com/ETJ57985

    返回:

    +----------+--------+---------+----------+
    | LastName | Boston | Chicago | New York |
    +----------+--------+---------+----------+
    | Black    |      2 |       1 |        0 |
    | Jones    |      0 |       1 |        0 |
    | Murphy   |      0 |       0 |        2 |
    | Simpson  |      0 |       0 |        1 |
    +----------+--------+---------+----------+
    

答案 1 :(得分:1)

我认为简单的数据透视将提供您的查询结果

Select * from (
    Select LastName, City from Example ) a
pivot (count(city) for city in ([New York],[Boston],[Chicago])) p

如果您更改下面的查询,您将获得适当的结果:

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
N'Select LastName, ' + @PivotSelectColumnNames + ' from ( SELECT LastName, City
    FROM Example ) a
    pivot(count(City) for City in (' + @PivotColumnNames + ')) as pvt';

输出如下:


+----------+----------+--------+---------+
| LastName | New York | Boston | Chicago |
+----------+----------+--------+---------+
| Black    |        0 |      2 |       1 |
| Jones    |        0 |      0 |       1 |
| Murhpy   |        1 |      0 |       0 |
| Murphy   |        1 |      0 |       0 |
| Simpson  |        1 |      0 |       0 |
+----------+----------+--------+---------+

答案 2 :(得分:0)

不使用PIVOT的替代方法:

DECLARE @sql NVARCHAR(max);
SET @sql = ''; -- not necessary for CONCAT, but necessary if converting this answer to + style string concatenation 

SELECT 
  @sql = CONCAT(@sql, ', COUNT(CASE WHEN city = ''', City, ''' THEN 1 END) as ', QUOTENAME(City))
FROM
  Example
GROUP BY City

SET @sql = CONCAT('SELECT Name', @sql, ' FROM example GROUP BY name')

EXEC sp_executesql @sql

答案 3 :(得分:0)

试试这个 -

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX),
        @PivotColumnNames AS NVARCHAR(MAX),
        @PivotSelectColumnNames AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column
SELECT @PivotColumnNames = ISNULL(@PivotColumnNames + ',','') + QUOTENAME(City)
FROM (SELECT DISTINCT City FROM #example) AS cat

--Get distinct values of the PIVOT Column with isnull
SELECT @PivotSelectColumnNames 
= ISNULL(@PivotSelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME(City) + ', 0) AS '
+ QUOTENAME(City)
FROM (SELECT DISTINCT City FROM #example) AS cat

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
N'SELECT LastName, ' + @PivotSelectColumnNames + '
FROM #example
pivot(count(City) for City in (' + @PivotColumnNames + ')) as pvt group by LastName, ' + @PivotColumnNames;

--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery