TSQL选择Prev Current Next的排序列

时间:2014-01-13 03:22:02

标签: sql sql-server algorithm tsql sorting

我有一个包含这些列的表:

+-----------+--------------+-----------+
|PrevStation|CurrentStation|NextStation|
+-----------+--------------+-----------+
|-          |A             |B          |
+-----------+--------------+-----------+
|A          |B             |C          |
+-----------+--------------+-----------+
|B          |C             |D          |
+-----------+--------------+-----------+
|C          |D             |E          |
+-----------+--------------+-----------+
|D          |F             |-          |
+-----------+--------------+-----------+

现在我希望通过以下方式代表一个视图:

+---------------+
|ClosestStations|
+---------------+
|A              |
+---------------+
|B              |
+---------------+
|C              |
+---------------+
|D              |
+---------------+
|E              |
+---------------+
|F              |
+---------------+

* 注意:我希望排序的行包含第一个表*

的合同

您如何看待解决方案?

3 个答案:

答案 0 :(得分:1)

试试这个

Select [CLoseStation] from
(
   select PrevStation AS [CLoseStation],PrevStation ,NextStation,CurrentStation
   From T
   Union
   Select NextStation AS [CLoseStation],PrevStation ,NextStation,CurrentStation
   From T
   union
   Select CurrentStation AS [CLoseStation],PrevStation ,NextStation,CurrentStation
   From T
) AS S Order By PrevStation ,NextStation,CurrentStation ASC

答案 1 :(得分:1)

你可以使用recursive query,但如果你有一个很长的链表,这将会非常低效

use tempdb
go

create table #stations (prev char, [current] char)

INSERT INTO #stations 
values (null, 'A'),
    ('A', 'B'),
    ('B', 'C'),
    ('C', 'D'),
    ('D', 'E'),
    ('E', 'F');

with rec (this, level)
AS (
    SELECT [current], 0 FROM #stations where prev is null
    UNION ALL
    SELECT [current], rl.level + 1
    FROM #stations sc
    INNER JOIN rec rl ON sc.prev = rl.this
)
SELECT *
FROM rec
ORDER BY level asc;

DROP TABLE #stations;

-- Produces
--this level
------ -----------
--A    0
--B    1
--C    2
--D    3
--E    4
--F    5

由于此链表样式表很难查询,因此您可能希望将其转换为有序表。使用循环将避免遇到MAXRECURSION

强加的限制
use tempdb
go

CREATE TABLE #stations (prev char, [current] char)

INSERT INTO #stations 
values (null, 'A'),
    ('A', 'B'),
    ('B', 'C'),
    ('C', 'D'),
    ('D', 'E'),
    ('E', 'F');

CREATE TABLE #stationPositions (station char, sequence int)

DECLARE @seq int = 0,
    @station char

SELECT TOP(1) @Station = [current]
FROM #stations
WHERE prev is null

WHILE 1=1
BEGIN
    INSERT INTO #stationPositions (station, sequence)
    VALUES (@station, @seq)

    SELECT TOP(1) @station = [current]
    FROM #stations
    WHERE prev = @station

    IF @@ROWCOUNT = 0 BREAK

    SET @seq = @seq + 1
END

SELECT * FROM #stationPositions

DROP TABLE #stations;
DROP TABLE #stationPositions;

-- Results:
--station sequence
--------- -----------
--A       0
--B       1
--C       2
--D       3
--E       4
--F       5

答案 2 :(得分:0)

我认为你想要一个union查询:

select station
from ((select PrevStation as station
       from t
      ) union
      (select NextStation
       from t
      ) union
      (select CurrentStation
       from t
      )
     ) t
where station is not null
order by station;