如何防止行SQL Pivot中的NULL字段?

时间:2018-11-08 03:57:33

标签: sql sql-server tsql database-design pivot

我正在针对varchar运行SQL Pivot。

我有下表:

`Continent    | State      | City
--------------------------------------------- 
North America | California | Oakland
North America | California | Los Angeles
North America | California | Sacramento
North America | California | San Diego
North America | California | San Francisco
North America | California | Upton
North America | Florida    | Jacksonville
North America | Florida    | Fort Lauderdale
North America | Florida    | Miami
North America | Florida    | Tampa
North America | New York   | Albany
North America | New York   | Buffalo
North America | New York   | New York
North America | New York   | Rochester
North America | New York   | Utica
North America | Texas      | Austin
North America | Texas      | Dallas
North America | Texas      | San Antonio`

我想创建一个如下所示的数据透视表:

`Continent     | California    | Florida         | New York    | Texas
-----------------------------------------------------------------------
North America | Oakland       | Jacksonville    | Albany      | Austin
North America | Los Angeles   | Fort Lauderdale | Buffalo     | Dallas
North America | Sacramento    | Miami           | New York    | San Antonio
North America | San Diego     | Tampa           | Rochester   | NULL
North America | San Francisco | NULL            | Utica       | NULL
North America | Upton         | NULL            | NULL        | NULL`

我当前正在使用以下代码:


`        SELECT *
        FROM
        (
            SELECT Placename.Continent,
                Placename.State,
                Placename.City,
                row_number() over(partition by Placename.State order by Placename.City) rn
                FROM Placename
        ) AS SourceTable PIVOT(Min(City) FOR [State] IN([California],
        [Florida],
        [New York],
        [Texas]
        )) AS PivotTable`

注意:Min(City)和Max(City)给了我相同的输出结果

现在,使用此代码后,将给出下表:

`Continent     | California    | Florida         | New York    | Texas
-----------------------------------------------------------------------
North America | Oakland       | Jacksonville    | NULL        | Austin
North America | NULL          | Fort Lauderdale | Albany      | Dallas
North America | Los Angeles   | NULL            | Buffalo     | NULL
North America | Sacramento    | Miami           | New York    | San Antonio
North America | NULL          | Tampa           | NULL        | NULL
North America | San Diego     | NULL            | Rochester   | NULL
North America | San Francisco | NULL            | Utica       | NULL
North America | Upton         | NULL            | NULL        | NULL`

输出的表与所需的表输出不同的原因是什么?

2 个答案:

答案 0 :(得分:2)

只需尝试:

DECLARE @tbl TABLE(Continent VARCHAR(100),[State] VARCHAR(100),City VARCHAR(100));
INSERT INTO @tbl VALUES
 ('North America','California','Oakland')
,('North America','California','Los Angeles')
,('North America','California','Sacramento')
,('North America','California','San Diego')
,('North America','California','San Francisco')
,('North America','California','Upton')
,('North America','Florida','Jacksonville')
,('North America','Florida','Fort Lauderdale')
,('North America','Florida','Miami')
,('North America','Florida','Tampa')
,('North America','New York','Albany')
,('North America','New York','Buffalo')
,('North America','New York','New York')
,('North America','New York','Rochester')
,('North America','New York','Utica')
,('North America','Texas','Austin')
,('North America','Texas','Dallas')
,('North America','Texas','San Antonio');

SELECT *
FROM
(
    SELECT Placename.Continent,
        Placename.State,
        Placename.City,
        row_number() over(partition by Placename.State order by Placename.City) rn
        FROM @tbl AS PlaceName
) AS SourceTable PIVOT(Min(City) FOR [State] IN([California],
[Florida],
[New York],
[Texas]
)) AS PivotTable;

这是完全您自己的查询,用于处理模型表。据我所知,结果正是您需要的结果:

+---------------+----+---------------+-----------------+-----------+-------------+
| Continent     | rn | California    | Florida         | New York  | Texas       |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 1  | Los Angeles   | Fort Lauderdale | Albany    | Austin      |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 2  | Oakland       | Jacksonville    | Buffalo   | Dallas      |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 3  | Sacramento    | Miami           | New York  | San Antonio |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 4  | San Diego     | Tampa           | Rochester | NULL        |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 5  | San Francisco | NULL            | Utica     | NULL        |
+---------------+----+---------------+-----------------+-----------+-------------+
| North America | 6  | Upton         | NULL            | NULL      | NULL        |
+---------------+----+---------------+-----------------+-----------+-------------+

如果还有更多内容,请使用上面的独立示例,建立一个像我这样的运行示例,并说明您还需要什么。

答案 1 :(得分:0)

这样的事情应该为你做。

--DROP TABLE #C
CREATE TABLE #C (X CHAR(1) , ID INT)
INSERT INTO #C values('A', 1)
INSERT INTO #C values(NULL, 2)
INSERT INTO #C values('B', 3)
INSERT INTO #C values('C', 4)
INSERT INTO #C values(NULL, 5)
INSERT INTO #C values('D', 6)

select *
from #C

enter image description here

SELECT ID,CASE WHEN X is not null
            THEN X
            ELSE (SELECT max(X)
                  FROM #C
                  WHERE ID <= t.ID)
       END AS X
FROM #C t 

enter image description here

如果其sql 2012使用此

SELECT ID,
COALESCE(Name,
LAG(Name,1) OVER (ORDER BY ID )) AS Name
FROM Table
If there can be multiple gaps use this instead
SELECT ID,
COALESCE(Name,
MAX(COALESCE(Name,'')) OVER (ORDER BY ID  ROWS BETWEEN UNBOUNDED PRECEDING AND  1 PRECEDING)) AS Name
FROM Table