我正在使用SQL Server 2014,我正在使用名为ReservationStay的表。它包含所有客人的姓名,抵达日期和出发日期的记录。已经开展了一项操作,将数百名客人的记录分成2个单独的条目,这意味着这些条目现在具有相同的客人姓名,但具有不同的到达日期和出发日期。
原始条目的示例:
Name ArrivalDate DepartureDate
Simon G 2015-06-01 2015-06-08
以下是拆分操作在2015-06-03之后发生的事情:
Name ArrivalDate DepartureDate
Simon G 2015-06-01 2015-06-03
Simon G 2015-06-03 2015-06-08
这项拆分行动在几天内进行。
我的查询中需要一个过滤器,它会考虑以下因素:
WHERE Name是重复的,第一个条目的DepartureDate =第二个条目的ArrivalDate。
基本上,我想重新构建原始条目。
如何编写此过滤器?
答案 0 :(得分:0)
可以使用简单的INNER JOIN
("自我加入")来完成:
SELECT a.Name, a.ArrivalDate, b.DepartureDate
FROM dtab a
INNER JOIN dtab b ON b.Name=a.Name
AND b.ArrivalDate=a.DepartureDate
见http://sqlfiddle.com/#!9/51ea3/2
我在表格中添加了几行,以便有一个不符合条件的示例:
CREATE TABLE dtab (Name varchar(11),ArrivalDate varchar(10),DepartureDate varchar(10));
INSERT INTO dtab (Name,ArrivalDate,DepartureDate)
VALUES
('Simon G', '2015-06-01', '2015-06-03'),
('Simon G', '2015-06-03', '2015-06-08'),
('Peter M', '2015-03-07', '2015-03-15'),
('Peter M', '2015-05-05', '2015-05-10');
并获得所需的结果
| Name | ArrivalDate | DepartureDate |
|---------|-------------|---------------|
| Simon G | 2015-06-01 | 2015-06-08 |
修改强>
注意,为了重建未拆分表,您还需要列出之前已拆分 的条目。为此,您可以执行以下操作:
WITH combined AS (
SELECT a.Name cnam, a.ArrivalDate carr, b.DepartureDate cdep
FROM dtab a
INNER JOIN dtab b ON b.Name=a.Name
AND b.ArrivalDate=a.DepartureDate
)
SELECT d.* FROM dtab d
LEFT JOIN combined ON cnam=Name AND (carr=ArrivalDate OR cdep=DepartureDate)
WHERE cdep IS NULL
UNION ALL
SELECT * FROM combined
我将原始的SELECT
语句放入公用表格表达式(combined
)中,并用它来检查原始表格中任何条目的到达或出发日期是否一致。如果是这样,原始条目将不列出,否则它们将在UNION
中列出combined
表的条目。
现在我们得到
| Name | ArrivalDate | DepartureDate |
|---------|-------------|---------------|
| Peter M | 2015-03-07 | 2015-03-15 |
| Peter M | 2015-05-05 | 2015-05-10 |
| Simon G | 2015-06-01 | 2015-06-08 |
见http://sqlfiddle.com/#!6/7d325/5
此解决方案将在SQL Server 2005中起作用(SQL Server 2012中引入了LAG / LEAP
)。
答案 1 :(得分:0)
declare @t table (name varchar(10),Arrivaldate varchar(20),Departure varchar(20))
insert into @t(name,Arrivaldate,Departure)
values
('Simon G','2015-06-01','2015-06-03'),
('Simon G','2015-06-03','2015-06-08')
Select A.name,A.Arrivaldate,A.Departure from (
select NAME,MIN(Arrivaldate)Arrivaldate,MAX(Departure)Departure from @t GROUP BY NAME)A
答案 2 :(得分:0)
您可以使用LEAD
,LAG
窗口函数来查找已拆分的记录:
SELECT Name, MIN(ArrivalDate) AS ArrivalDate, MAX(DepartureDate) AS DepartureDate
FROM (
SELECT Name, ArrivalDate, DepartureDate,
CASE
WHEN ArrivalDate = LAG(DepartureDate) OVER (PARTITION BY Name
ORDER BY ArrivalDate)
OR
DepartureDate = LEAD(ArrivalDate) OVER (PARTITION BY Name
ORDER BY ArrivalDate)
THEN 1
ELSE 0
END AS HasBeenSplit
FROM mytable ) t
GROUP BY Name, HasBeenSplit
此查询将为您提供表格的原始版本。