我要计算飞行路线的二氧化碳排放量。航班行程可以包含1跳,例如DXB / CDG或ABJ / ADD / BKK / KUL / ADD / ABJ,共5跳。我的挑战是我需要将行程信息分解为单独的航班信息,因为每次航班都会计算出二氧化碳排放量:
来源:ABJ/ADD/BKK/KUL/ADD/ABJ
并将其转换为:
答案 0 :(得分:1)
我建议采用这种方法:
DECLARE @fligth VARCHAR(100)='ABJ/ADD/BKK/KUL/ADD/ABJ';
WITH Casted(flightXML) AS
(SELECT CAST('<x>' + REPLACE(@fligth,'/','</x><x>') + '</x>' AS XML))
,Tally(Nmbr) AS
(SELECT TOP((SELECT flightXML.value('count(/x)','int') FROM Casted)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values)
SELECT flightXML.value('(/x[sql:column("Nmbr")]/text())[1]','varchar(10)') AS FromAirport
,flightXML.value('(/x[sql:column("Nmbr")+1]/text())[1]','varchar(10)') AS ToAirport
FROM Casted
CROSS JOIN Tally
WHERE flightXML.value('(/x[sql:column("Nmbr")+1]/text())[1]','varchar(10)') IS NOT NULL;
想法:
我们通过将分隔符替换为标签,将分隔的字符串转换为XML。这样我们就得到
<x>ABJ</x>
<x>ADD</x>
<x>BKK</x>
<x>KUL</x>
<x>ADD</x>
<x>ABJ</x>
现在,XQuery允许as按其位置检索值。因此,第二个CTE创建了一个即时提示。它将返回从到n的运行数字,其中n是字符串中的停靠点数。
最终查询将使用sql:column()
将计数编号引入XQuery。您可以将其读取为在位置<x>
上找到Nmbr
并返回其内容。现在在位置<x>
上找到Nmbr+1
。
答案 1 :(得分:0)
要获得预期的结果,您可以创建一个函数,该函数将使用提供的定界符将字符串分成行。之后,您可以根据需要进行进一步调整或对返回的数据进行更改。
步骤1:创建函数
dist^2
步骤2:使用该功能获取所需数据
sqrt
输出将是-
CREATE FUNCTION [dbo].[splitstring] ( @stringToSplit VARCHAR(MAX) ,@Delimiter VARCHAR(10))
RETURNS @returnList TABLE ([Word] [nvarchar] (500))
AS
BEGIN
DECLARE @name NVARCHAR(255)
DECLARE @pos INT
WHILE CHARINDEX(@Delimiter, @stringToSplit) > 0
BEGIN
SELECT @pos = CHARINDEX(@Delimiter, @stringToSplit)
SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)
INSERT INTO @returnList
SELECT @name
SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
END
INSERT INTO @returnList
SELECT @stringToSplit
RETURN
END
您还可以使用如下所示的SQL LEAD函数获得以上输出-
SELECT A.Word+'/'+B.Word FROM
(
SELECT Word,
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM [dbo].[splitstring]('ABJ/ADD/BKK/KUL/ADD/ABJ','/')
) A
INNER JOIN
(
SELECT Word,
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM [dbo].[splitstring]('ABJ/ADD/BKK/KUL/ADD/ABJ','/')
)B ON A.RN = B.RN-1