2012-10-05 76 views
1

鑑於表:總結取決於多個條件:轉換爲單個查詢

reservations (id, place_id, confirmed_at, paid_at)places (id, name)

我需要返回可單獨表達瞭如下的查詢彙總:

-- Confirmed 
SELECT places.id, places.name, COUNT(reservations.*) as total_confirmed 
FROM reservations 
    INNER JOIN places ON places.id = reservations.place_id 
WHERE 
    reservations.confirmed_at IS NOT NULL 
GROUP BY places.id, places.name 

-- Paid 
SELECT places.id, places.name, COUNT(reservations.*) as total_paid 
FROM reservations 
    INNER JOIN places ON places.id = reservations.place_id 
WHERE 
    reservations.paid_at IS NOT NULL 
GROUP BY places.id, places.name 

-- Paid Uncofirmed 
SELECT places.id, places.name, COUNT(reservations.*) as total_paid_unconfirmed 
FROM reservations 
    INNER JOIN places ON places.id = reservations.place_id 
WHERE 
    reservations.paid_at IS NOT NULL AND reservations.confirmed_at IS NULL 
GROUP BY places.id, places.name 

我如何重寫這些查詢到一個單一的並返回所有必要的?

回答

1

我希望有這樣的查詢,因爲什麼,如果有一些places有沒有reservation又或者可能有多個預訂了。仍然可以安全地計算SUM

SELECT d.*, a.total_confirmed, b.total_paid, c.total_paid_unconfirmed 
FROM places d 
     LEFT JOIN 
     (
      SELECT places.id, places.name, COUNT(reservations.*) as total_confirmed 
      FROM reservations 
       INNER JOIN places ON places.id = reservations.place_id 
      WHERE 
       reservations.confirmed_at IS NOT NULL 
      GROUP BY places.id, places.name 
     ) a ON d.id = a.id 
     LEFT JOIN 
     (
      SELECT places.id, places.name, COUNT(reservations.*) as total_paid 
      FROM reservations 
       INNER JOIN places ON places.id = reservations.place_id 
      WHERE 
       reservations.paid_at IS NOT NULL 
      GROUP BY places.id, places.name 
     ) b ON d.id = b.id 
     LEFT JOIN 
     (
      SELECT places.id, places.name, COUNT(reservations.*) as total_paid_unconfirmed 
      FROM reservations 
       INNER JOIN places ON places.id = reservations.place_id 
      WHERE 
       reservations.paid_at IS NOT NULL AND reservations.confirmed_at IS NULL 
      GROUP BY places.id, places.name 
     ) c ON d.id = c.id 
3
SELECT places.id, places.name, 
sum(case when (reservations.confirmed_at IS NOT NULL) then 1 else 0 end) as total_confirmed, 
sum(case when (reservations.paid_at IS NOT NULL) then 1 else 0 end) as total_paid, 
sum(case when (reservations.paid_at IS NOT NULL AND reservations.confirmed_at IS NULL) then 1 else 0 end) as total_confirmed_paid 
FROM reservations 
    INNER JOIN places ON places.id = reservations.place_id 
GROUP BY places.id, places.name 
+0

我懷疑你的查詢有一定的錯別字,你叫三列「total_confirmed」 – DaveRlz

+0

什麼,如果有一些地方有沒有保留或可能有多個預約嗎?它會影響'SUM'。 –

+0

你可以檢查它.. – jainvikram444

1

這些查詢可以通過工會結合在一起,但在工會的所有查詢必須返回相同的結果集,對於所有查詢的輸出必須做出相同。這是可以做到如下:

SELECT places.id, places.name,'total_confirmed' as totalType, COUNT(reservations.*) as total 
FROM reservations INNER JOIN places ON places.id = reservations.place_id 
WHERE reservations.confirmed_at IS NOT NULL 
GROUP BY places.id, places.name 
union all 
SELECT places.id, places.name,'total_paid' as totalType, COUNT(reservations.*) as total 
FROM reservations INNER JOIN places ON places.id = reservations.place_id 
WHERE reservations.paid_at IS NOT NULL 
GROUP BY places.id, places.name 
union all 
SELECT places.id, places.name,'total_paid_unconfirmed' as totalType, COUNT(reservations.*) as total 
FROM reservations INNER JOIN places ON places.id = reservations.place_id 
WHERE reservations.paid_at IS NOT NULL AND reservations.confirmed_at IS NULL 
GROUP BY places.id, places.name