2017-02-14 3 views
0

Мне нужно определить количество продаж за неделю и на выходные, но выходные дни должны быть учтены с 18:00 до 9:00 понедельника.t-SQL Группировка по дням и часам

Например, если у меня есть ниже данные:

2017-02-09 14:00 
2017-02-09 19:00 
2017-02-10 17:15 
2017-02-10 18:22 
2017-02-11 11:00 
2017-02-11 16:00 
2017-02-12 19:30 
2017-02-13 08:00 
2017-02-14 14:00 

Я хотел бы получить следующее:

Weekday: 4 
Weekend: 5 

Его довольно легко получить продаж в день, используя что-то вроде:

select count(*) as total, dateadd(DAY,0, datediff(day,0, created) as created 
from sales 
group by dateadd(DAY,0, datediff(day,0, created)) 

Но я не могу подумать, как совместить часы и дни, чтобы получить требуемую информацию.

+0

пожалуйста помечать DBMS, показать некоторые выборочные данные и ожидаемый результат. –

+0

Можете ли вы показать некоторые данные образца и требуемый вывод. Также, пожалуйста, отметьте СУБД, с которой вы используете – TheGameiswar

+0

'dateadd (день, 0' вы не добавляете ни одного дня – McNets

ответ

2

Это просто сложное заявление case. Вы можете сделать это с помощью outer apply и использовать значение для агрегации:

select weekpart, count(*) 
from sales s outer apply 
    (values (case when datename(dw, created) in ('Tuesday', 'Wednesday', 'Thursday') then 'Weekday' 
        when datename(dw, created) = 'Monday' and 
         datepart(hh, created) >= 9 
        then 'Weekday' 
        when datename(dw, created) = 'Friday' and 
         datepart(hh, created) < 18 
        then 'Weekday' 
        else 'Weekend' 
       end) 
    ) v(weekpart) 
group by v.weekpart; 

Это намеренно использует datename() для будних дней. В настройках интернационализации на день недели влияют. Все англоязычные страны имеют одинаковые имена для недельных дней, но местные соглашения могут повлиять на дату начала недели. Я также считаю, что для неанглийской настройки код довольно ясен, почему он не будет работать - таким образом, что по сравнению с «1» нет.

+0

Спасибо. Это отлично сработало. – Steve

+0

Должно быть 18 вместо 6 для 6 вечера. –

+0

Да! Было бы просто сказать, что 6 должно быть заменено на 18 – Steve

0

Это поможет вам начать работу:

with CTE as 
(
select dateadd(hh, datepart(hh,created), dateadd(dd,0, datediff(dd,0,created))) as created_dayhour, 
     someothercolumn, 
     datepart(dw,created) as create_day, 
     datepart(hh, created) as create_hour 
from sales 
) 
select created_dayhour, count(someothercolumn) 
from CTE 
group by created_dayhour 
1

Попробуйте что-то вроде этого:

SELECT week_or_weekend, count(*) 
FROM 
(
    SELECT 1 as cnt, CASE WHEN 
    DATEPART(DW, created) in (7,1) 
    OR 
    (DATEPART(DW, created) 6 AND DATEPART(hour, created) >= 18) 
    OR 
    (DATEPART(DW, created) 2 AND DATEPART(hour, created) < 9) 
    THEN 'WEEKEND' 
    ELSE 'WEEK' 
    END week_or_weekend 
    FROM sales 
) q 
GROUP BY week_or_weekend 

Пояснение: DW = 7 стендов для субботу, 1 на воскресенье, 6 на пятницу, 2 понедельник Я добавляю 1 как cnt для пояснения, потому что это бесполезно, если вы не добавите отдельного в подзапрос. Вы можете сделать это в 1 запросе, но вам придется повторить дважды большой оператор «case when end».

1
with CTE as 
(
select created, 
    case when 
    (datepart(dw,[created]) = 6 and datepart(hh,created) >= 18) or 
    (datepart(dw,created)=7 or datepart(dw,created)=1) or 
    (datepart(dw,[created]) = 2 and datepart(hh,created) <= 9) 
    then 'Weekend' 
    else 'Weekday' end as weekType 
from Table1) 
select weekType, count(1) 
from CTE 
group by weekType 

Проверьте это здесь: http://sqlfiddle.com/#!6/4fbb0/8