如何将行转换为具有聚合函数的列来自两个或多个表?

时间:2015-01-20 05:16:11

标签: sql sql-server aggregate multiple-tables

我想从车站获取名字,我将在火车的汇总功能中添加此名称。这是我的结构:

站:

CREATE TABLE station
(ID int, Name varchar(100))
;

INSERT INTO station
    (ID, Name)
VALUES
    (1, 'Luka'),
    (2, 'Lisbon'),
    (3, 'Singapore'),
    (4, 'Banyuwangi'),
    (5, 'Gresik'),
    (6, 'Paris');

火车:

CREATE TABLE train
    (ID int, Name varchar(100), StationID int, TimeStamp datetime)
;

INSERT INTO train
    (ID, Name,StationID, TimeStamp)
VALUES
    (1, 'Arrived', 1,'2015-01-15 20:31:17.287'),
    (2, 'Go',1,'2015-01-15 20:32:17.287'),
    (3, 'Arrived', 2,'2015-01-16 20:31:17.287'),
    (4, 'Go',2,'2015-01-16 20:32:17.287'),
    (5, 'Arrived', 3,'2015-01-17 20:31:17.287'),
    (6, 'Go',3,'2015-01-17 20:32:17.287'),
    (7, 'Arrived', 4,'2015-01-18 20:31:17.287'),
    (8, 'Go',4,'2015-01-18 20:32:17.287'),
    (9, 'Arrived', 5,'2015-01-19 20:31:17.287'),
    (10, 'Go',5,'2015-01-19 20:32:17.287'),
    (11, 'Arrived', 6,'2015-01-20 20:31:17.287'),
    (12, 'Go',6,'2015-01-20 20:32:17.287')
        ;

我想要这样的结果:

Station Name |Arrived  |Time                    |Go | Time
Luka         |Arrived  |2015-01-15 20:31:17.287 |Go |2015-01-15 20:32:17.287
Lisbon       |Arrived  |2015-01-16 20:31:17.287 |Go |2015-01-16 20:32:17.287
Singapore    |Arrived  |2015-01-17 20:31:17.287 |Go |2015-01-17 20:32:17.287
Banyuwangi   |Arrived  |2015-01-18 20:31:17.287 |Go |2015-01-18 20:32:17.287
Gresik       |Arrived  |2015-01-19 20:31:17.287 |Go |2015-01-19 20:32:17.287
Paris        |Arrived  |2015-01-20 20:31:17.287 |Go |2015-01-20 20:32:17.287

这是我的聚合查询,但我只是查看stationid而不是名称:

select stationid,
max(case when seq = 1 then name end) ARRIVED,
max(case when seq = 1 then timestamp end) TIME,
max(case when seq = 2 then name end) GO,
max(case when seq = 2 then timestamp end) TIME
from
(
    select b.stationid,b.name,b.timestamp,
    row_number() over(partition by b.stationid order by b.name) seq
    from station a, train b
    where  a.id = b.stationid and b.name not like '%reset%'
) schedule
group by stationid

之前感谢

2 个答案:

答案 0 :(得分:0)

最简单的方法(不是最好的方法)是将name添加到group by并将其添加到select

select stationName,
max(case when seq = 1 then name end) ARRIVED,
max(case when seq = 1 then timestamp end) TIME,
max(case when seq = 2 then name end) GO,
max(case when seq = 2 then timestamp end) TIME
from
(
    select b.stationid,b.name,a.name stationName,b.timestamp,
    row_number() over(partition by b.stationid order by b.name) seq
    from station a, train b
    where  a.id = b.stationid and b.name not like '%reset%'
) schedule
group by stationid, stationName

请注意,我仍然stationid位于group by以处理重复的name

SQLFiddle

答案 1 :(得分:0)

使用公用表表达式

WITH C AS(
    select stationid,
    max(case when seq = 1 then name end) ARRIVED,
    max(case when seq = 1 then timestamp end) TIME1,
    max(case when seq = 2 then name end) GO,
    max(case when seq = 2 then timestamp end) TIME2
    from
    (
        select b.stationid,b.name,b.timestamp,
        row_number() over(partition by b.stationid order by b.name) seq
        from station a, train b
        where  a.id = b.stationid and b.name not like '%reset%'
    ) schedule
    group by stationid
)
SELECT station.name, C.ARRIVED, C.TIME1 AS TIME, C.Go, C.TIME2 AS TIME
FROM C INNER JOIN station ON C.stationid = station.id