2012-03-22 172 views
1

我需要一個幫助頭腦風暴的查詢。我有一個銷售表,每個餐廳位置有兩行(每天)。一行是AM銷售,另一行是PM銷售。 AM銷售實際上只是AM銷售,然而,PM銷售是AM銷售和PM銷售的組合。因此,爲了提取PM銷售額,您必須從其中減去AM銷售額。MySQL查詢 - 兩行之間的差異

--------------------------------------------------------- 
    date | id | meridiem | daily_sales | cover_counts | 
--------------------------------------------------------- 
2012-03-22 |103 | AM  | 2956.32 | 175  | 
2012-03-22 |103 | PM  | 12124.62 | 484  | 
--------------------------------------------------------- 

我有一個查詢來計算預計午餐每人平均(這是從AM銷售),它很好。它基本上從前6周的銷售數據中提取前四周,並對其進行平均。 (注:按人均銷售額除以銷售額計算)。

$statement = "SELECT directory.location, ROUND((SUM(sales.daily_sales/sales.cover_counts)/4), 2) AS lppa 
       FROM t_directory directory 
       LEFT JOIN t_sales sales 
       ON sales.site_id = directory.site_id 
       AND DAYOFWEEK(sales.business_date) = DAYOFWEEK(:date1) 
       AND sales.business_date < DATE_SUB(:date2, INTERVAL 14 DAY) 
       AND sales.business_date >= DATE_SUB(:date3, INTERVAL 42 DAY)     
       AND sales.meridiem = 'AM' 
       WHERE directory.active = 1 
       GROUP BY directory.site_id 
       ORDER BY directory.site_id ASC 
       LIMIT :totalLocations"; 

$statementHandle = $this->dbHandle->prepare($statement); 
$statementHandle->bindValue(':date1', $this->date, PDO::PARAM_STR); 
$statementHandle->bindValue(':date2', $this->date, PDO::PARAM_STR); 
$statementHandle->bindValue(':date3', $this->date, PDO::PARAM_STR); 
$statementHandle->bindValue(':totalLocations', $this->totalLocations, PDO::PARAM_INT); 
$statementHandle->execute(); 
$lppa = $statementHandle->fetchAll(PDO::FETCH_ASSOC); 

現在我想計算每人的平均晚餐。爲了做到這一點,我將不得不減去AM銷售額,並分別在PM算出任何數學之前從PM銷售額和蓋子中扣除。有沒有一種簡單的方法來實現這一切到一個查詢?我明顯可以用PHP來做到這一點,但我只是很好奇這是如何在查詢中完成的。任何幫助或見解將不勝感激。請讓我知道是否需要更多細節。

回答

2

可以做重新加入到t_sales中,然後過濾 'PM'

SELECT DIRECTORY.location, 
     Round((SUM(salesPM.daily_sales - salesAM.daily_sales/
        salesPM.cover_counts - salesAM.cover_counts)/4), 2) 
         AS lppaPM 
FROM t_directory DIRECTORY 
     LEFT JOIN t_sales salesAM 
     ON salesAM.site_id = DIRECTORY.site_id 
      AND Dayofweek(salesAM.business_date) = Dayofweek(:date1) 
      AND salesAM.business_date < DATE_SUB(:date2, INTERVAL 14 DAY) 
      AND salesAM.business_date >= DATE_SUB(:date3, INTERVAL 42 DAY) 
      AND salesAM.meridiem = 'AM' 
     LEFT JOIN t_sales salespm 
     ON salesAM.site_id = salesPM.site_id 
      AND salesAM.business_date = salesPM.business_date 
      AND salespm.meridiem = 'PM' 
WHERE DIRECTORY.active = 1 
GROUP BY DIRECTORY.site_id 
ORDER BY DIRECTORY.site_id ASC 
LIMIT :totalLocations 

注:此解決方案假定

  • {Site_ID, business_Date, meridiem}是唯一
  • 從未有一個PM沒有AM記錄的記錄
  • salesPM.cover_counts - salesAM.cover_counts永不等於零
+0

@Brett - - (注意康拉德),爲了得到正確的封面,你必須從封面上減去早上的封面o你知道晚上有多少食客... – DRapp 2012-03-22 17:17:58

+0

@DRapp謝謝我會更新,但我只是做了一個faceplam看Andomor的解決方案 – 2012-03-22 17:18:51

+0

我不認爲這是正確的總和。第二個左連接將包含第一個左連接中每一行的重複行。 – Andomar 2012-03-22 17:33:29

1

從連接條件刪除此:

AND sales.meridiem = 'AM' 

然後你可以選擇:

ROUND((SUM(case when sales.meridiem = 'AM' 
       then sales.daily_sales/sales.cover_counts end)/4), 2) as AMSum 
ROUND((SUM(case when sales.meridiem = 'PM' 
       then sales.daily_sales/sales.cover_counts end)/4), 2) as PMSum 

從PM減去AM,你可以:

SUM(case sales.meridiem 
    when 'PM' then sales.daily_sales/sales.cover_counts 
    when 'AM' then - sales.daily_sales/sales.cover_counts 
    end) as am_minus_pm 
+0

它將從PM中減去AM的位置? – Brett 2012-03-22 17:20:08