2009-06-24 5 views
3

주어진 테이블 :SQL Server 2005에서 주문, 시간, 요일별 주문 요약을 만드는 가장 효율적인 방법은 무엇입니까?

create table #orders (
    orderid int, 
    orderdatetime datetime 
) 

sql을 사용하여 현재 및 이전 24 시간의 주문 수, 당일 및 이전 7 일의 총 주문, 총 주문을 포함하는 보고서를 출력하는 가장 좋은 방법은 무엇입니까? 이번 주 및 지난 4 주간, 그리고 그 달 및 이전 6 개월 동안의 총 주문량은?

이 분석 함수를 사용하여 단일 SQL로 효율적으로 겹쳐서 수 또는 4 개의 데이터 그룹을 생성하는 4 sql 문을 유일한 (또는 최상의) 방법은 경우 궁금하네요.

또한 시간별/일별/주별 그룹화를 통해 SQL Server에서 어떻게 처리 할 수 ​​있습니까? Datetimes 내가 이런 식으로 뭔가를해야 할 때마다 엉덩이에 고통이 될 것 ...

아이디어? SSAS 큐브에 넣고 거기에서 할 수 있을까요?

+0

한 행 또는 여러 행으로 출력합니까? –

+0

@Peter 질문에 대한 답이 이미 있습니다. 필요한 것은 아닙니다.하지만 필자가 필요로하는 그룹화 및 필터링을 얻을 수 있습니다. – TheSoftwareJedi

답변

6
SELECT DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime), COUNT(*) 
FROM #orders 
GROUP BY 
     DATEPART(month, orderdatetime), DATEPART(week, orderdatetime), DATEPART(day, orderdatetime) WITH ROLLUP 

이 의지 그룹을 일, 주 및 월로 COUNT 년대를.

일주일 롤업은이 NULLDATEPART(day, orderdatetime)에, 달 롤업 모두 DATEPART(day, orderdatetime)DATEPART(week, orderdatetime) 열에서 NULL있을 것이다 것입니다.

WITH q_hours AS 
     (
     SELECT 0 AS col_hour 
     UNION ALL 
     SELECT col_hour + 1 
     FROM q_hours 
     WHERE col_hour < 22 
     ), 
     q_days AS 
     (
     SELECT 0 AS col_day 
     UNION ALL 
     SELECT col_day + 1 
     FROM q_days 
     WHERE col_day < 31 
     ), 
     q_months AS 
     (
     SELECT 0 AS col_month 
     UNION ALL 
     SELECT col_month + 1 
     FROM q_months 
     WHERE col_month < 12 
     ) 
SELECT col_month, col_day, col_hour, COUNT(orderid) 
FROM q_hours 
CROSS JOIN 
     q_days 
CROSS JOIN 
     q_months 
LEFT JOIN 
     #orders 
ON  DATEDIFF(month, orderdatetime, GETDATE()) = col_month 
     AND DATEDIFF(day, orderdatetime, GETDATE()) % 31 = col_day 
     AND DATEDIFF(hour, orderdatetime, GETDATE()) % 24 = col_hour 
GROUP BY 
     col_month, col_day, col_hour WITH ROLLUP 
HAVING (
     col_month = 0 
     AND col_day = 0 
     AND col_hour IS NOT NULL 
     ) -- all hours within 24 hours from now 
     OR 
     (
     col_month = 0 
     AND col_day <= 7 
     AND col_hour IS NULL 
     ) -- all days within 7 days from now 
     OR 
     (
     col_month <= 6 
     AND col_day IS NULL 
     AND col_hour IS NULL 
     ) -- all months within 6 months from now 
+0

하루 종일 테이블을 만들고 그 시간에 합류하는 것 외에 항상 매 시간마다 쉽게 만들 수있는 방법이 있습니까? – TheSoftwareJedi

+0

질문에 각 날짜 부분에 대해 다른 범위가 지정되어 있습니다.이 쿼리는 단일 범위에 대한 모든 개수를 제공합니다. –

+0

완벽한 편집. 이것은 정확하게 내가 작업하고 있던 것입니다. 게시했을 때 거의 완료되었습니다. 다음 번에 빨리하십시오. LOO;) – TheSoftwareJedi

0

당신은 "더미 테이블"에서 네 가지 선택을 실행할 수 또는 "정체성 :

CTE 년대를 사용 틈없이 현재에서 매 시간, 일, 주 또는 월을 위해 그것을하기 위해 "단일 행으로 구성된 테이블.

당신은 할 수 :

SELECT 
    (<query count of orders current/prev 24 hours>) as <name1>, 
    (<total orders current + 7 days>) as <name2>, 
    (<total orders current week + 4 weeks>) as <name3>, 
    (<total orders month + 6 months>) as <name4> 
FROM 
<IDENTITY table>; 
0

각 날짜 부분 유형에 대해 서로 다른 시간대를 원하기 때문에, 아마 당신이 원하는 걸주지 않을 것이다 롤업으로 단일 쿼리를 사용. 나는 이것들을 모두 함께 결합하는 것을 고려할 것이다 ...

SELECT DatePartValue = DATEPART(HH, orderdatetime), 
     Type = 'Hourly', 
     COUNT(*) 
FROM #orders 
WHERE orderdatetime > DATEADD(HH, -25, GETDATE()) 
GROUP BY DATEPART(HH, orderdatetime) 
UNION 
SELECT DATEPART(DD, orderdatetime), 
     Type = 'Daily', 
     COUNT(*) 
FROM #orders 
WHERE orderdatetime > DATEADD(DD, -8, GETDATE()) 
GROUP BY DATEPART(DD, orderdatetime) 
UNION 
SELECT DATEPART(WEEK, orderdatetime), 
     Type = 'Weekly', 
     COUNT(*) 
FROM #orders 
WHERE orderdatetime > DATEADD(WEEK, -5, GETDATE()) 
GROUP BY DATEPART(WEEK, orderdatetime) 
ORDER BY Type, DatePartValue 
UNION 
SELECT DATEPART(MM, orderdatetime), 
     Type = 'Monthly', 
     COUNT(*) 
FROM #orders 
WHERE orderdatetime > DATEADD(MM, -7, GETDATE()) 
GROUP BY DATEPART(MM, orderdatetime) 
ORDER BY Type, DatePartValue 
0

나는 그룹화 세트를 원한다고 생각한다. SQL Server 그룹화 집합을 지원하는 이해했습니다.

EDIT1 : 나는 SQL Server 2005가 그룹화 집합을 지원하지 않지만 SQL Server 2008에서는 지원한다는 것을 읽었습니다. 여기에 mapreduce와 오라클 및 SQL Server와 같은 rdbms 사이의 기존의 차이는 없지만 재미있는 내용이 있습니다. 의견도 읽어주세요 !! 이 같은 하나의 행, 뭔가 결과를 http://www.data-miners.com/blog/2008/01/mapreduce-and-sql-aggregations.html

0
SELECT  
    sum(case when orderdatetime between GetDate() - 1 and GetDate() then 1 else 0 end) as Current24Hours, 
    sum(case when orderdatetime between GetDate() - 2 and GetDate() - 1 then 1 else 0 end) as Previous24Hours, 
    sum(case when orderdatetime between GetDate() - 7 and GetDate() then 1 else 0 end) as Current7Days, 
    sum(case when orderdatetime between GetDate() - 14 and GetDate() - 7 then 1 else 0 end) as Previous7Days, 
    sum(case when DATEDIFF (m, OrderDate, @now) <= 1 then 1 else 0 end) as PreviousMonth, 
    sum(case when DATEDIFF (m, OrderDate, @now) <= 6 then 1 else 0 end) as PreviousSixMonths 
FROM orders 
0

는 :

select 
    orders_day = sum(case when datediff(hour,orderdatetime,getdate()) < 24 then 1 else 0 end) 
, orders_week = sum(case when datediff(day,orderdatetime,getdate()) < 7 then 1 else 0 end) 
, orders_month = sum(case when datediff(week,orderdatetime,getdate()) < 4 then 1 else 0 end) 
, orders_half = sum(case when datediff(month,orderdatetime,getdate()) < 6 then 1 else 0 end) 
from #orders 

당신은 적절한 행동을 얻기 위해 미세 조정 날짜 기준을 할 수 있습니다.

여러 행의 경우 위에 나온 결과를 UNPIVOT 또는 CASE .. CROSS JOIN으로 조 변경하십시오.

관련 문제