2016-04-21 3 views
1

У меня есть следующая таблица температуры, которая была построена в список текущего состояния гостиничного номера в отелеКак объединить несколько строк в одном строк

declare @CurrentDate datetime = '2016-04-21' 
    select Lodging, Room, FirstName, LastName, TempStatus, @CurrentDate as CurrentDate 
    from RoomAvailability 

Это следующий результат:

Lodging  Room FirstName LastName TempStatus CurrentDate 
    ------------------------------------------------------------------------------- 
    marriok  119  Super  Man  Next guest  2016-03-24 00:00:00.000 
    marriok  101  Bat   Man  Next guest  2016-03-24 00:00:00.000 
    marriok  123  Aqua  Man  Leaving today 2016-03-24 00:00:00.000 
    marriok  103  Wonder  Woman Leaving today 2016-03-24 00:00:00.000 
    marriok  101  Lex   Luthor Leaving today 2016-03-24 00:00:00.000 

Это мой ожидаемый результат:

Lodging  Room CurrFirstName  CurrLastName TempStatus  CurrentDate     NextFistName NextLastName TempStatus 
    ---------------------------------------------------------------------------------------------------------------------------------------------- 
    marriok  119  Super    Man    Next guest  2016-03-24 00:00:00.000  NULL   NULL   NULL 
    marriok  123  Aqua    Man    Leaving today 2016-03-24 00:00:00.000  NULL   NULL   NULL 
    marriok  103  Wonder    Woman   Leaving today 2016-03-24 00:00:00.000  NULL   NULL   NULL 
    marriok  101  Lex     Luthor   Leaving today 2016-03-24 00:00:00.000  Bat    Man    Next guest 

Я попытался это:

declare @CurrentDate datetime = '2016-04-21' 
    select coalesce(a.Lodging, b.Lodging) as Lodging, 
     coalesce(a.Room, b.Room) as Room, 
     a.FirstName as CurrFirstName, a.LastName as CurrLastName, a.TempStatus, @CurrentDate, 
     b.NextFirstName, b.NextLastName, b.TempStatus 
    from RoomAvailability a 
    full join RoomAvailability b 
     on a.Lodging = b.Lodging 
     and a.Room = b.Room 

И я получил это:

Lodging  Room CurrFirstName  CurrLastName TempStatus  CurrentDate     NextFistName NextLastName TempStatus 
    ---------------------------------------------------------------------------------------------------------------------------------------------- 
    marriok  119  Super    Man    Next guest  2016-03-24 00:00:00.000  Super   Man    Next guest 
    marriok  101  Bat     Man    Next guest  2016-03-24 00:00:00.000  Bat    Man    Next guest 
    marriok  101  Bat     Man    Next guest  2016-03-24 00:00:00.000  Lex    Luthor   Leaving today 
    marriok  123  Aqua    Man    Leaving today 2016-03-24 00:00:00.000  Aqua   Man    Leaving today 
    marriok  103  Wonder    Woman   Leaving today 2016-03-24 00:00:00.000  Wonder   Woman   Leaving today 
    marriok  101  Lex     Luthor   Leaving today 2016-03-24 00:00:00.000  Bat    Man    Next guest 
    marriok  101  Lex     Luthor   Leaving today 2016-03-24 00:00:00.000  Lex    Luthor   Leaving today 

Так как я могу получить уникальные или объединить строки и список людей, кто покидающих и прибывающих в той же комнате, в тот же день? (Предпочтительнее без КТР)


Update

ТЕмп стол RoomAvailability был продукт из 3-х отдельных утверждений с союзом все

В 3 выберите оператора одинаковы, просто они отличаются на где условие. В этих трех операциях select содержатся столбцы datetime для регистрации и выписки.

Мой первый выбор фильтруется текущей переменной даты между датой регистрации и регистрации (не включенной). Я добавил столбца как статус «В доме».

Мой второй выбор фильтруется текущей переменной даты равно проверить в и я добавил текст статуса «Следующий гость»

Последние выберите фильтруется текущей переменной даты приравнивает к проверке, и я добавил статус «Покидать сегодня».


Update 2

Это ближе, что я мог бы получить без КТР

select coalesce(a.Lodging, b.Lodging), 
    coalesce(a.Room, b.Room), 
    a.FirstName, a.LastName, a.TempStatus, 
    b.FirstName, b.LastName, b.TempStatus, 
    @CurrentDate 
from RoomAvailability a 
left join RoomAvailability b 
    on a.Lodging = b.Lodging 
    and a.Room = b.Room 
    and a.TempStatus != b.TempStatus 

Но это повторять строки для одной и той же комнате, в конце

marriok 119 Super Man  Next guest  NULL NULL NULL   2016-04-21 
marriok 101 Bat  Man  Next guest  Lex  Luthor Leaving today 2016-04-21 
marriok 123 Aqua Man  Leaving today NULL NULL NULL   2016-04-21 
marriok 103 Wonder Woman Leaving today NULL NULL NULL   2016-04-21 
marriok 101 Lex  Luthor Leaving today Bat  Max  Next guest  2016-04-21 --<-- this should not be displayed 
+1

поставить запрос в подзапрос, добавить row_number, раздел за комнатой и d order by tempstatus .. тогда во внешнем запросе выберите where row_number = 1 .. вот один пример http://stackoverflow.com/questions/6841605/get-top-1-row-of-each-group – JamieD77

+0

у вас есть уникальный ключ в вашем столе? – FLICKER

+0

@FLICKER, ну просто идентификатор комнаты и комнаты. Эта таблица была построена из запроса с объединениями, чтобы получить сводку дня, но мы не хотим дублировать. –

ответ

1

Если бы вы были на SQL 2012 и позже, окончательный запрос был бы проще.

Если предположить, что ваши данные в таблице с именем #t

данные настройки

create table #t (
    Lodging varchar(10) 
    , Room int 
    , FirstName varchar(10) 
    , LastName varchar(10) 
    , TempStatus varchar(20) 
    , CurrentDate datetime 
) 

insert into #t values 
('marriok'  ,119  ,'Super'  ,'Man'  ,'Next guest'  ,'2016-03-24'), 
('marriok'  ,101  ,'Bat'   ,'Man'  ,'Next guest'  ,'2016-03-24'), 
('marriok'  ,123  ,'Aqua'  ,'Man'  ,'Leaving today' ,'2016-03-24'), 
('marriok'  ,103  ,'Wonder'  ,'Woman' ,'Leaving today' ,'2016-03-24'), 
('marriok'  ,101  ,'Lex'   ,'Luthor' ,'Leaving today' ,'2016-03-24') 

Ваш запрос будет

with sortIt as (
    select *, case TempStatus 
        when 'Next guest' then 2 
        when 'Leaving today' then 1 
       end as Sort 
    from #t 
) 
, addFld as (
    select t1.*, t2.FirstName as NextFirstName, t2.LastName as NextLastName 
     , t2.TempStatus as NextTempStatus 
    from sortIt t1 
     left join sortIt t2 on t2.Room = t1.Room and t2.Sort = t1.Sort + 1 
) 
, removDup as ( 
    select *, ROW_NUMBER() over (partition by Room order by NextFirstName desc) rn 
    from addFld 
) 
select * from removDup 
where rn = 1 

Результат

+---------+------+-----------+----------+---------------+-------------------------+------+---------------+--------------+----------------+----+ 
| Lodging | Room | FirstName | LastName | TempStatus |  CurrentDate  | Sort | NextFirstName | NextLastName | NextTempStatus | rn | 
+---------+------+-----------+----------+---------------+-------------------------+------+---------------+--------------+----------------+----+ 
| marriok | 101 | Lex  | Luthor | Leaving today | 2016-03-24 00:00:00.000 | 1 | Bat   | Man   | Next guest  | 1 | 
| marriok | 103 | Wonder | Woman | Leaving today | 2016-03-24 00:00:00.000 | 1 | NULL   | NULL   | NULL   | 1 | 
| marriok | 119 | Super  | Man  | Next guest | 2016-03-24 00:00:00.000 | 2 | NULL   | NULL   | NULL   | 1 | 
| marriok | 123 | Aqua  | Man  | Leaving today | 2016-03-24 00:00:00.000 | 1 | NULL   | NULL   | NULL   | 1 | 
+---------+------+-----------+----------+---------------+-------------------------+------+---------------+--------------+----------------+----+ 
+0

Я не знаю, что вы имеете в виду с Sql2012. Это также работает с 2008 годом, это использование CTE. Я думал, что с полным соединением это может быть проще, но я сдаюсь. Потому что я так не понимаю CTE, но спасибо, что ваш ответ спас день. Очень благодарен! –

+1

В sql 2012 вы можете использовать функции LAG и LEAD, которые делают окончательный запрос намного короче. В любом случае, я рад, что это помогло – FLICKER

Смежные вопросы