Редизайн часов работы - PullRequest
       4

Редизайн часов работы

0 голосов
/ 10 февраля 2020

Я работаю над требованием, которое имеет данные «Часы работы», как показано ниже:

enter image description here

Данные здесь должны отображаться в по-другому. Значение: я пытаюсь объединить часы работы в днях и часы открытия / закрытия. Мой ожидаемый результат:

enter image description here

Возможно ли достичь этого набора результатов? Я создал временную таблицу с этими данными в приведенной ниже ссылке rextester.

https://rextester.com/EMF48033

Код:

select programid, 
       concat(max(case when [order] = 1 then day end),' ','-',' ', max(case when [order] = max_order then day end)) as day,
       times
from (select programid, day, [order], max([order]) over (partition by programid) as max_order,
             STUFF((SELECT ',' + concat([open], ' ','-',' ', [close]) FOR XML PATH ('')), 1, 1, '') as times
      from #temp
      group by programid, day, [order],[open], [close]
     ) pd
group by programid, times
order by times desc

Ответы [ 2 ]

3 голосов
/ 10 февраля 2020

Для ваших примеров данных это работает:

select programid, 
       concat_ws('-', max(case when [order] = 1 then day end), max(case when [order] = max_order then day end)) as day,
       times
from (select programid, day, [order], max([order]) over (partition by programid) as max_order,
             string_agg(concat([open], '-', [close]), '\n') within group (order by convert(time, [open])) as times
      from temp
      group by programid, day, [order]
     ) pd
group by programid, times;

Здесь - это дБ <> скрипка.

0 голосов
/ 11 февраля 2020

Я не знаю, будете ли вы довольны 'и' вместо новой строки, но это работает в SQL 2012. Использование cross apply выглядит немного громоздким, но это потому, что я бы определите его один раз, чтобы запустить left, а не повторяйте его:

 ;

with cte as (
    select
    programid,
    t1.[day],
    [order],
    left(ot.OpeningTimes,len(ot.OpeningTimes)-4) as OpeningTimes,
    min(t1.[order]) over (partition by t1.programid order by t1.[order] asc) as StartOrder,
    max(t1.[order]) over (partition by t1.programid order by t1.[order] desc) as EndOrder
    from #temp as t1
    cross apply (
        select (
            select concat([open],' - ',[close], ' and ')
            from #temp as t2
            where t1.programid = t2.programid
                and t1.[day] = t2.[day]
            for xml path('')
        ) as OpeningTimes
        from #temp as t3
        where t1.programid = t3.programid
            and t1.[day] = t3.[day]
    ) as ot 
    group by programid, [day], [order], OpeningTimes
    )

select
cte.programid,
concat(sd.[day],' - ',ed.[day]) as OpeningDays,
cte.OpeningTimes
from cte
inner join cte as sd on sd.programid = cte.programid
        and sd.[order] = sd.StartOrder
inner join cte as ed on ed.programid = cte.programid
        and ed.[order] = ed.EndOrder
group by cte.programid, sd.[day], ed.[day], cte.OpeningTimes
...