我在SQL Server中有一个如下表
+---+-------------+-------------+-------------+ |Id | FromCity | ToCity | RequestId | +---+-------------+-------------+-------------+ | 1 | Mysore | Atlanta | 12 | +---+-------------+-------------+-------------+ | 2 | Atlanta | Singapore | 12 | +---+-------------+-------------+-------------+ | 3 | Singapore | Pakistan | 12 | +---+-------------+-------------+-------------+ | 4 | Pakistan | Myscot | 12 | +---+-------------+-------------+-------------+ | 5 | Rome | Singapore | 13 | +---+-------------+-------------+-------------+
在这里,我正在尝试获取“从城市到目的地”(往返数据)的值(即Mysore-> Myscot for RequestId = 12 )。何获得此值?
当我传递RequestId = 12时,我应该获得的值为迈索尔->迈斯科特
我尝试如下:
SELECT MIN(FromCity) [From],
MAX(ToCity) [To]
FROM MyTable
WHERE RequestId = 12
但是我要到迈索尔->新加坡(基于字符串MIN和MAX)。
答案 0 :(得分:2)
答案 1 :(得分:1)
我看到的唯一逻辑是使用表中的Id
并执行类似的操作。使用CTE
,您将找到每个请求的MIN
和MAX
ID,即从城市到城市。
之后,将表加入CTE以查找实际值。
declare @tbl as table
([Id] int, [FromCity] varchar(9), [ToCity] varchar(9), [Date Created] datetime, [RequestId] int)
;
INSERT INTO @tbl
([Id], [FromCity], [ToCity], [Date Created], [RequestId])
VALUES
(1, 'Mysore', 'Atlanta', '2018-10-05 15:10:00', 12),
(2, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 12),
(3, 'Singapore', 'Pakistan', '2018-10-07 15:10:00', 12),
(4, 'Pakistan', 'Myscot', '2018-10-07 15:10:00', 12),
(5, 'UK', 'Atlanta', '2018-10-06 15:10:00', 13),
(6, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 13),
(7, 'Singapore', 'Italy', '2018-10-23 15:10:00', 13);
;with cte as (
select
MIN(Id) as [start]
,MAX(Id) as [end]
,RequestId
from @tbl
group by requestID
)
select
t1.FromCity
,t1.[Date Created]
,t2.ToCity
,t2.[Date Created]
from cte
inner join @tbl t1
on t1.Id = cte.[start]
and t1.RequestId = cte.RequestId
inner join @tbl t2
on t2.Id = cte.[end]
and t2.RequestId = cte.RequestId
更新:基于@Panagiotis Kanavos评论,您可以像这样简化查询
;with cte as (
select
MIN(Id) as [start]
,MAX(Id) as [end]
from @tbl
where RequestId = 12 ---> here you can use a variable containing the requestID
)
select
t1.FromCity
--,t1.[Date Created]
,t2.ToCity
--,t2.[Date Created]
from cte
inner join @tbl t1
on t1.Id = cte.[start]
inner join @tbl t2
on t2.Id = cte.[end]
答案 2 :(得分:1)
如果使用主表中的ID来描述旅行顺序,那么类似的方法将起作用:
SELECT startLocation.FromCity [From], endLocation.ToCity AS [To]
FROM (
SELECT MIN(Id) AS StartLocationId, MAX(Id) AS EndLocationId
FROM MyTable
WHERE RequestId = 12
) AS a
INNER JOIN MyTable AS startLocation ON a.StartLocationId = startLocation.Id
INNER JOIN MyTable AS endLocation ON a.EndLocationId = endLocation.Id
这是当id只是id并且与旅行顺序不匹配时的解决方案的示例:
declare @tbl as table
([Id] int, [FromCity] varchar(9), [ToCity] varchar(9), [Date Created] datetime, [RequestId] int)
;
INSERT INTO @tbl
([Id], [FromCity], [ToCity], [Date Created], [RequestId])
VALUES
(19, 'Mysore', 'Atlanta', '2018-10-05 15:10:00', 12),
(22, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 12),
(1, 'Singapore', 'Pakistan', '2018-10-07 15:10:00', 12),
(4, 'Pakistan', 'Myscot', '2018-10-07 15:10:00', 12),
(5, 'UK', 'Atlanta', '2018-10-06 15:10:00', 13),
(0, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 13),
(-1, 'Singapore', 'Italy', '2018-10-23 15:10:00', 13)
;
select * from @tbl
declare @Id int = 12
declare @FromStart nvarchar(255), @ToStart nvarchar(255)
declare @StartResult nvarchar(255), @ToResult nvarchar(255)
declare @StartResultFound bit = 0, @ToResultFound bit = 0
-- select random starting point
select @FromStart = [FromCity], @ToStart = [ToCity] from @tbl where [RequestId] = @Id
ORDER BY NEWID()
select @FromStart, @ToStart
while (@StartResultFound = 0)
begin
if exists (select top 1 1 from @tbl where [RequestId] = @Id and [ToCity] = @FromStart)
begin
select top 1 @FromStart = [FromCity] from @tbl where [RequestId] = @Id and [ToCity] = @FromStart
end
else
begin
set @StartResultFound = 1
set @StartResult = @FromStart
end
end
while (@ToResultFound = 0)
begin
if exists (select top 1 1 from @tbl where [RequestId] = @Id and [FromCity] = @ToStart)
begin
select top 1 @ToStart = [ToCity] from @tbl where [RequestId] = @Id and [FromCity] = @ToStart
end
else
begin
set @ToResultFound = 1
set @ToResult = @ToStart
end
end
select @StartResult, @ToResult
答案 3 :(得分:1)
SELECT RequestId,
f.FromCity [From],
t.ToCity [To]
FROM MyTable t
CROSS APPLY (
SELECT TOP (1) FromCity
FROM MyTable
WHERE RequestId = t.RequestId
ORDER BY Id ASC
) f
CROSS APPLY (
SELECT TOP (1) ToCity
FROM MyTable
WHERE RequestId = t.RequestId
ORDER BY Id DESC
) t
WHERE RequestId = 12
答案 4 :(得分:1)
递归版本,不取决于conda install -c krisvanneste kivy
的顺序。这个想法是要建立往返于城市之间的最大旅行链。
Id
答案 5 :(得分:1)
也许这是您需要的
DECLARE
@t TABLE (
ID INT
, FromCity VARCHAR(250)
, ToCity VARCHAR(250)
, RequestId INT
)
INSERT INTO @t VALUES
(1,'Mysore','Atlanta',12)
,(2,'Atlanta','Singapore',12)
,(3,'Singapore','Pakistan',12)
,(4,'Pakistan','Myscot',12)
,(5,'Rome','Singapore',13)
SELECT DISTINCT
ISNULL(FromCity, ISNULL(NextCity, PreCity) ) FromCity
, ISNULL(ToCity, ISNULL(NextCity2, PreCity2) ) FromCity
FROM (
SELECT
CASE WHEN RN = 1 THEN FromCity END FromCity
, CASE WHEN RN = CNT THEN ToCity END ToCity
, LEAD(CASE WHEN RN = 1 THEN FromCity END) OVER(PARTITION BY RequestId ORDER BY ID) NextCity
, LEAD(CASE WHEN RN = CNT THEN ToCity END) OVER(PARTITION BY RequestId ORDER BY ID) NextCity2
, LAG(CASE WHEN RN = 1 THEN FromCity END) OVER(PARTITION BY RequestId ORDER BY ID) PreCity
, LAG(CASE WHEN RN = CNT THEN ToCity END) OVER(PARTITION BY RequestId ORDER BY ID) PreCity2
FROM (
SELECT
*, ROW_NUMBER() OVER(PARTITION BY RequestId ORDER BY ID) RN
, COUNT(ToCity) OVER(PARTITION BY RequestId) CNT
FROM @t
) D
WHERE
RN = 1 OR RN = CNT
) C
答案 6 :(得分:0)
尝试此代码
SELECT MIN(Id)[从], MAX(Id)[收件人] 从MyTable 其中RequestId = 12