2017-07-14 5 views
1

Ich versuche, eine Abfrage in SQL Server basierend auf Datumzeit und Wochentag zu schreiben, wo meine Ausgabe sein sollte:Gruppendaten durch Intervall von 15 Minuten und verwenden Kreuztabelle

enter image description here

Meine Tabellenbeschreibungen sind:

**Branch**(DateKey integer, 
    BranchName varchar2(20), 
    TransactionDate datetime, 
    OrderCount integer) 

    **Date**(DateKey integer PrimaryKey, 
    DayNameofWeek varchar2(15)) 

Dies ist die Rohdaten I

Data

haben So
+0

Hier ist eine sehr ähnliche Frage: https://stackoverflow.com/questions/830792/t-sql-round-to-nearest-15-minute-interval Der einzige Unterschied ist, dass Sie auf die nächsten 15min runden würden DOWN und in dieser Frage wird direkt auf NEXT gerundet. – swe

+0

Möchten Sie nur für die Zeitspanne zwischen 11:30 und 12:30 eine Abfrage durchführen oder gibt es noch mehr Werte? –

+0

@maulik Es ist für mehr als die Werte, dies ist nur ein Beispiel. Ich brauche es für 24 Stunden. – Shivang

Antwort

0

, ist dies eine recht lange gedreht, aber ich löste es auf folgende Weise:

ich eine table valued function geschaffen, die eine date als Parameter übernehmen würde und alle 15-minute Abständen im Laufe des Tages finden. Für jeden Tag würde es von 00:00, to 00:15, 00:30 bis zu 23:30, 23:45 und 23:59 gehen. Es gibt auch jedes Intervall start time und end time, da wir in Ihrem branch Tabelle für jede Zeile dieses verwenden müssen zu überprüfen, ob sie in diesem Zeitschlitz fallen und wenn ja, zählen sie in

Dies ist die Funktion:.

create function dbo.getDate15MinIntervals(@date date) 
returns @intervals table (
    [interval] int not null, 
    [dayname] varchar(20) not null, 
    interval_start_time datetime not null, 
    interval_end_time datetime not null 
) 
as 
begin 

    declare @starttime time = '00:00'; 
    declare @endtime time = '23:59'; 

    declare @date_start datetime; 
    declare @date_end datetime; 
    declare @min datetime; 

    select @date_start = cast(@date as datetime) + cast(@starttime as datetime), @date_end = cast(@date as datetime) + cast(@endtime as datetime); 

    declare @minutes table ([date] datetime) 

    insert into @minutes values (@date_start), (@date_end) -- begin, end of the day 

    select @min = DATEADD(mi, 0, @date_start) 

    while @min < @date_end 
    begin 
     select @min = DATEADD(mi, 1, @min) 
     insert into @minutes values (@min) 
    end 

    insert into @intervals 
    select ([row]-1)/15+1 intervalId, [dayname], min(interval_time) interval_start_time 

    > -- **NOTE: This line is the only thing you need to change:** 

    , DATEADD(ms, 59998, max(interval_time)) interval_end_time 


    from 
    (
     select row_number() over(order by [date]) as [row], [date], datename(weekday, [date]) [dayname], [date] interval_time 
     from @minutes 
    ) t 
    group by ([row]-1)/15+1, [dayname] 
    order by ([row]-1)/15+1 

    return 

end 

--example of calling it: 
select * from dbo.getDate15MinIntervals('2017-07-14') 

Dann bin ich Ihr branch Tabelle abfragt (die Sie nicht wirklich brauchen die Date Tisch, der Wochentag, jetzt haben Sie es in der Funktion aber selbst wenn nicht, gibt es eine DATENAME Funktion in SQL Server, mit ab 2008 die Sie verwenden können ..

würde ich Ihre Tabelle wie folgt abfragen:

select branchname, [dayname], ISNULL([11:30], 0) as [11:30], ISNULL([11:45], 0) as [11:45], ISNULL([12:00], 0) as [12:00], ISNULL([12:45], 0) as [12:45] 
from 
( 
    select intervals.[dayname] 
     , b.branchname 
     , convert(varchar(5), intervals.interval_start_time, 108) interval_start_time -- for hh:mm format 
     , sum(b.ordercount) ordercount 
    from branch b cross apply dbo.getDate15MinIntervals(CAST(b.TransactionDate as date)) as intervals 
    where b.transactiondate between interval_start_time and interval_end_time 
    group by intervals.[dayname], b.branchname, intervals.interval_start_time, intervals.interval_end_time 
) t 
pivot (sum(ordercount) for interval_start_time in ([11:30], [11:45] , [12:00], [12:45])) as p 

Bitte beachten Sie, ich in der PIVOT Funktion haben nur die Intervalle I im Bild sehen können Sie auf dem Laufenden, aber natürlich können Sie alle 15-minute Intervalle des Tages schreiben manuell - Sie müssten sie nur einmal in die pivot und einmal in die select Anweisung schreiben - oder optional diese Anweisung dynamically generieren.

+0

Es gibt mir keine richtige Anzahl von Intervallen. Beispiel, für 11:45 - 11:59 zählt es nicht richtig, denn 11:59:28 ist es ausgeschlossen oder kann Duplikate sein, weil 2 Datensätze um 11:59. – Shivang

+0

Sie können "BETWEEN" durch '> = und <=' ersetzen, obwohl "BETWEEN" beide Daten enthält. –

+0

Es ist immer noch der gleiche Ausgang .. jede andere Lösung, die Sie sich vorstellen können? – Shivang

Verwandte Themen