SQL 服务器 : splitting a column to multiple columns with joined table

标签 sql sql-server

我有 3 个表 A、B、C

表A

sID sName
1   Apple
2   Banana
3   Cherry

表B

PointID PointName sID
1       seed      1
2       seed      2
3       stem      1
4       stem      2
5       stem      3
6       root      2
7       leave     1

表C

PointID Time                  pointValue
1       2013-03-15 12:00:00   23.0
2       2013-03-15 12:00:00   24.0
5       2013-03-15 12:00:00   25.0
1       2013-03-15 13:00:00   26.0
2       2013-03-15 13:00:00   27.0
6       2013-03-15 13:00:00   28.0
2       2013-03-16 13:00:00   29.0
6       2013-03-16 13:00:00   30.0
7       2013-03-15 13:00:00   31.0

我需要这样的输出(简单地显示按时间过滤的所有结果):

Time                  sName    seed    stem   root
2013-03-15 12:00:00   Apple    23.0    NULL   NULL 
2013-03-15 12:00:00   Banana   24.0    NULL   NULL
2013-03-15 12:00:00   Cherry   NULL    25.0   NULL
2013-03-15 13:00:00   Apple    26.0    NULL   NULL   
2013-03-15 13:00:00   Banana   27.0    NULL   28.0

我想出了一个使用多个连接的解决方案,但是我的结果确实显示了时间和带有种子、茎、根的 sName 为 NULL,因为不需要 pointName“leave”。

SELECT HEADER.TIME
    ,HEADER.sName
    ,SD.seed
    ,STM.stem
    ,RT.root
FROM (
    SELECT C.TIME
        ,A.sName
    FROM B
    INNER JOIN C ON B.PointID = C.PointID
    INNER JOIN A ON B.sID = A.sID
    ) HEADER
FULL JOIN (
    SELECT C.TIME
        ,A.sName
    FROM B
    INNER JOIN C ON B.PointID = C.PointID
    INNER JOIN A ON B.sID = A.sID
    WHERE B.PointName = "seed"
    ) SD ON HEADER.TIME = SD.TIME
    AND HEADER.sName = SD.sName
FULL JOIN (
    SELECT C.TIME
        ,A.sName
    FROM B
    INNER JOIN C ON B.PointID = C.PointID
    INNER JOIN A ON B.sID = A.sID
    WHERE B.PointName = "stem"
    ) STM ON HEADER.TIME = STM.TIME
    AND HEADER.sName = STM.sName
FULL JOIN (
    SELECT C.TIME
        ,A.sName
    FROM B
    INNER JOIN C ON B.PointID = C.PointID
    INNER JOIN A ON B.sID = A.sID
    WHERE B.PointName = "root"
    ) RT ON HEADER.TIME = RT.TIME
    AND HEADER.sName = RT.sName
WHERE (HEADER.TIME > '2013-03-15 11:00:00')
    AND (HEADER.TIME < '2013-03-16 20:00:00')

我试图在最外层的 where 子句中添加一个 OR 子句,以检查 3 列之一是否不为空。但是却没有返回结果

WHERE (HEADER.Time > '2013-03-15 11:00:00') AND (HEADER.Time < '2013-03-16 20:00:00') 
AND (SD.seed <> NULL OR STM.stem <> NULL OR RT.root <> NULL)

如果能解决NULL选择就好了,或者有更好的解决办法评论一下?因为我不确定我当前的方法是否适用于具有更多多列的实现

最佳答案

我相信您需要一个 PIVOT为此,鉴于需要将行数据投影到列中:

SELECT Date, sName, [seed], [stem], [root], [leave]
FROM
(
   SELECT DATE, [PointName], [sName], PointValue
   FROM C 
     LEFT JOIN B ON C.PointID = B.POINTID
     LEFT JOIN A ON B.[sID] = A.[sID]
) p
PIVOT
(
  SUM(PointValue)
  FOR [PointName] IN ( [seed], [stem], [root], [leave])
) y;

SqlFiddle

关于SQL 服务器 : splitting a column to multiple columns with joined table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27583609/

相关文章:

php - 在MYSQL中使用WHERE时可以使用多个参数吗

java - 有关服务器、数据库和 android 的问题

sql - 在 Rails 中使用 Filterrific 搜索 Active Record 关联

sql - 如何检索两个相似字符之间的值

sql - SQL Server 中的 BETWEEN

java - 通过 Java 将超大数据集加载到关系数据库的最佳实践

c# - 使用 Microsoft.SqlServer.Dac.DacServices 在单用户模式下发布 dacpac

SQL Server 2000 - "Actual Number of Rows"到底是什么?

sql - 验证类型 2 缓慢变化的维度表

mysql 到 mssql 的混合字段分组