2012-03-24 2 views
1

나는 쿼리 번호가 이고 현재 (52 주)이되도록 쿼리를 변경하려고합니다. 이 쿼리는 일정 범위의 날짜 목록이 포함 된 캘린더 테이블을 사용합니다. 쿼리는 최대 및 최소 날짜를 선택하는 것이지 마지막 52 주일 필요는 없습니다.현재 52 주 동안 주별 항목 수를 계산하는 MySQL 쿼리?

지난 52 주 (즉, 1 년 전부터 지금까지)를 얻을 수 있도록 현재 캘린더 테이블을 최신 상태로 유지하는 방법을 알고 싶습니다. 아니면 달력 테이블을 사용하지 않고 쿼리를 독립적으로 만들 수있는 또 다른 방법이 있습니까?

SELECT calendar.datefield AS date, IFNULL(SUM(purchaseyesno),0) AS item_sales 
FROM items_purchased join items on items_purchased.item_id=items.item_id 
RIGHT JOIN calendar ON (DATE(items_purchased.purchase_date) = calendar.datefield) 
WHERE (calendar.datefield BETWEEN (SELECT MIN(DATE(purchase_date)) 
FROM items_purchased) AND (SELECT MAX(DATE(purchase_date)) FROM items_purchased)) 
GROUP BY week(date) 

생각 : 여기

쿼리입니까?

+0

왜 캘린더 테이블이 있고 그 테이블에 DATE 또는 DATETIME 열을 사용하지 않는 이유가 무엇입니까? –

+0

일정표는 각 기간마다 보관함이 있어야하고 특정 보관함에 대한 데이터가 없을 때 사용됩니다. –

+0

@ Ryan Kempt, 그것이 실제로 OP가 요구하는 것일 수 있습니다. 또한 일련의 날짜가 필요할 때 날짜 기능이 도움이되지 않습니다. –

답변

1

어떤 사람들은이 방법을 싫어하지만 0의 값을 포함하는 더미 테이블을 사용하는 경향이 -

CREATE TABLE dummy (`num` INT NOT NULL); 
INSERT INTO dummy VALUES (0), (1), (2), (3), (4), (5), .... (999), (1000); 

당신은 테이블이있는 경우 - 필요한 범위를 생산하기 위해 1000 다음 파생 테이블을 사용 자동으로 증가하는 ID와 많은 행을 가지고 생성 할 수 있습니다. -

CREATE TABLE `dummy` 
SELECT id AS `num` FROM `some_table` WHERE `id` <= 1000; 

그냥 0 값을 삽입해야합니다. @Sql 변수를 사용하여

SELECT WEEK(calendar.datefield) AS `week`, IFNULL(SUM(purchaseyesno),0) AS item_sales 
FROM items_purchased join items on items_purchased.item_id=items.item_id 
RIGHT JOIN (
    SELECT (CURRENT_DATE - INTERVAL num DAY) AS datefield 
    FROM dummy 
    WHERE num < 365 
) AS calendar ON (DATE(items_purchased.purchase_date) = calendar.datefield) 
WHERE calendar.datefield >= (CURRENT_DATE - INTERVAL 1 YEAR) 
GROUP BY week(datefield) -- shouldn't this be datefield instead of date? 
+0

안녕하세요 nnichols, 정말 고마워요, 제가이 기회를 포기할 것입니다. 왜 사람들은이 접근법을 좋아하지 않습니까? 코드가보기 싫어 보이니까? 또는 쿼리가 느립니까? 또는...? –

+0

이유가 확실하지 않습니다.이 문제는 전혀 발생하지 않아야하며 개인적으로는 다소 우아한 해결책이라고 생각합니다. – nnichols

+0

나는 더미 테이블을 만들었습니다. 조언을 주셔서 감사합니다. 그러나, 나는 당신의 진술에 특히 혼란 스럽다고 생각합니다 :'where calendar.datefield> = (CURRENT_DATE - INTERVAL 1 YEAR)'. 그대로, 2008 년 1 월에서 2010 년 9 월까지 내 캘린더 테이블이 바뀝니다. 평등 함으로 인해 지난 1 년 이내에 내 캘린더 테이블을 계속 업데이트해야합니까? 그건 그렇고,'week (group) by group (weekly) '이 아니라'group by week (datefield)'이면 52 주간의 아이템 판매가 발생합니다. 'date'가 정의되지 않았습니다. 그러나, 나는이 52 주간의 물품 판매가 가장 최근 52 주인지 아닌지 아직 확실하지 않습니다. 생각? –

1

내가 너무 일반적으로 즉석에서 테이블을 "시뮬레이션"그냥 ANY에 가입 -

SELECT CURRENT_DATE - INTERVAL num DAY 
FROM dummy 
WHERE num < 365 

따라서, 쿼리에이 방법을 적용하면이 뭔가를 할 수 있습니다 당신이 원하는만큼의 주를 가지고있는 당신의 시스템의 테이블. 참고 사항 ... 날짜를 다룰 때 일반적으로 오전 12시를 의미하는 날짜 부분 만 사용하고 싶습니다. 또한 "EndOfWeek"에 대한 시작일을 7 일로 앞당기면 주간 필요와 같은 주어진 기간 내에 레코드에 BETWEEN 절을 적용 할 수 있습니다. 내가 조정하는 등의 샘플을 적용한

조인 주 단위로 날짜 연결에 따라 ... 당신의

select 
     DynamicCalendar.StartOfWeek, 
     COALESCE(SUM(IP.PurchaseYesNo), 0) as Item_Sales 
    from 
     (select 
       @weekNum := @weekNum +1 as WeekNum, 
       @startDate as StartOfWeek, 
       @startDate := date_add(@startDate, interval 1 week) EndOfWeek 
      from 
       (select @weekNum := 0, 
         @startDate := date(date_sub(now(), interval 1 year))) sqlv, 
       AnyTableThatHasAtLeast52Records, 
      limit 
      52) DynamicCalendar 
     LEFT JOIN items_purchased IP 
     on IP.Purchase_Date bewteen DynamicCalendar.StartOfWeek 
          AND DynamicCalendar.EndOfWeek 
    group by 
     DynamicCalendar.StartOfWeek 

때문에 이것은 당신의 "PurchaseYesNo"값에 전제 당신의 직접 테이블을 구입했습니다. 그렇다면 ITEMS 테이블에 참여할 필요가 없습니다. 필드가 항목 테이블에있는 경우 항목 테이블에 LEFT JOIN을 붙이고 그 값을 얻습니다.

그러나 많은 조건에서 dynamicCalendar 컨텍스트를 사용할 수 있습니다.