2015-07-02 76 views
2

所以我有一個查詢,我試圖運行。現在它運行在代碼中的一個循環中,並對每個鄰居ID進行選擇。我寧願它做一個單一的選擇,只是循環通過這些結果,因爲這是少得可憐的數據庫imho。總之,我想不通爲什麼這兩個查詢給了我不同的結果:當我覺得它應該是相同的時獲得不同的SQL結果

首先查詢:

SELECT `neighbourhood_id`, 
    SUM(IF(`c`.`listing_offer` = 1, 1, 0)) as `listing_for_sale`, 
    AVG(IF(`c`.`listing_offer` = 1, `price`, 0)) as `avg_sale_price`, 
    SUM(IF(`c`.`listing_offer` = 2, 1, 0)) as `listing_for_rent`, 
    AVG(IF(`c`.`listing_offer` = 2, `price`, 0)) as `avg_rent_price` 
FROM (
    SELECT `n`.`id` AS `neighbourhood_id`, `l`.* 
    FROM `listing` `l` 
     LEFT JOIN `address` `a` ON `l`.`address_id` = `a`.`id` 
     LEFT JOIN `address_neighbourhood` `an` ON `a`.`id` = `an`.`address_id` 
     LEFT JOIN `neighbourhood` `n` ON `an`.`neighbourhood_id` = `n`.`id` 
     WHERE (`l`.`deleted`=0) 
      AND `n`.`id` IS NOT NULL 
      AND `n`.`id` = 1 
     GROUP BY `l`.`id` 
    ) `c` 
GROUP BY `neighbourhood_id` 

結果:

neighbourhood_id listing_for_sale avg_sale_price listing_for_rent avg_rent_price 
1     7541    486634.853967 4045    786.372706 

第二個查詢:

SELECT `neighbourhood_id`, 
    SUM(IF(`c`.`listing_offer` = 1, 1, 0)) as `listing_for_sale`, 
    AVG(IF(`c`.`listing_offer` = 1, `price`, 0)) as `avg_sale_price`, 
    SUM(IF(`c`.`listing_offer` = 2, 1, 0)) as `listing_for_rent`, 
    AVG(IF(`c`.`listing_offer` = 2, `price`, 0)) as `avg_rent_price` 
FROM (
    SELECT `n`.`id` AS `neighbourhood_id`, `l`.* 
    FROM `listing` `l` 
     LEFT JOIN `address` `a` ON `l`.`address_id` = `a`.`id` 
     LEFT JOIN `address_neighbourhood` `an` ON `a`.`id` = `an`.`address_id` 
     LEFT JOIN `neighbourhood` `n` ON `an`.`neighbourhood_id` = `n`.`id` 
     WHERE (`l`.`deleted`=0) 
      AND `n`.`id` IS NOT NULL 
     GROUP BY `l`.`id` 
    ) `c` 
WHERE `neighbourhood_id` = 1 
GROUP BY `neighbourhood_id` 

結果:

neighbourhood_id listing_for_sale avg_sale_price listing_for_rent avg_rent_price 
1     5740    522544.830430 2870    762.646690 

我敢肯定,查詢1是正確的結果,所以我不知道爲什麼我得到的第二個查詢不同的結果。我認爲要糾正哪一個是正確的。

任何幫助非常感謝。其中條件是由使用然後

+0

在第二種情況下,內部的「GROUP BY」可以分組排它確實有街坊= 1&也有一些其他的值返回其他值中的一個作爲選擇結果中的鄰域。 – PaulF

+0

在第一個查詢中是_「AND'n'.'id' IS NOT NULL」_是必要的,因爲子句的下一部分是_「AND'n'.'''' = 1」_這是互斥的 – PaulF

+0

@PaulF 'IS NOT NULL'在那裏,因爲我想刪除'n.id = 1'並得到所有社區的結果。 – SynackSA

回答

0

首先組濾波記錄集。現在的關鍵是它沒有必要維持秩序。您的兩個查詢的子查詢都以不同的順序返回結果,並在此之後爲過濾器創建問題。

的條件是AND附近. ID = 1在第一中查詢表子查詢'c'的where子句中這種情況是在主查詢的WHERE子句。這意味着在第二個查詢的子查詢c的記錄集可以有neighbourhoodid除1之外的值以及在該組之後的使用哪個記錄的值可以是該記錄集中的任何記錄的記錄。但在第一個子查詢中,只有那些記錄集被選中,其中neighbourhoodid = 1 e並通過結果記錄可以有value neighbourhood的記錄。 id = 1。

例如 你的第二個查詢的子查詢c具有導選擇具有n.id = 0一個紀錄,但這一紀錄將被拒絕,因爲這裏n.id=1是測試,不使用,因此內部查詢結果在外部查詢不使用。但是在第一個查詢的子查詢中,c將選擇那些n.id=1並且它總是用在外部查詢中的記錄。因此兩個結果都不一樣

假設子查詢c是 -

SELECT `l`.`id` , `n`.id 
    FROM `listing` `l` 
     LEFT JOIN `address` `a` ON `l`.`address_id` = `a`.`id` 
     LEFT JOIN `address_neighbourhood` `an` ON `a`.`id` = `an`.`address_id` 
     LEFT JOIN `neighbourhood` `n` ON `an`.`neighbourhood_id` = `n`.`id` 
     WHERE (`l`.`deleted`=0) 
      AND `n`.`id` IS NOT NULL; 

是結果

(l.id , n.id) (1,0),(1,1) 

當組由使用它return-

(l.id , n.id) (1,0) 

並且該記錄未在使用外查詢。

但在第一查詢子查詢的結果將是

(l.id , n.id) (1,1) 

,它是在外部查詢使用。

+0

我還是不太明白。在第一個查詢中,內部選擇只選擇'n.id = 1'的記錄,所以外部查詢不會丟棄任何東西。使用第二個查詢,它選擇所有記錄,但外部查詢然後放棄所有不是'n.id = 1'的記錄。在我看來,這是相同的,第一個在內部查詢中過濾/丟棄,第二個在外部查詢中完成。我認爲我誤解了這裏的一些基礎 – SynackSA

+0

@SynackSA我已經設置了示例 –

+0

您的評論讓我回過頭來看看我的數據,以及爲什麼該語句是由'l.id'分組的。我的'address_neighbourhood'表有很多重複的數據。我修復了表格和數據,這讓我的生活變得更加輕鬆,以至於我現在可以在單個查詢中做我想做的事情。謝謝 – SynackSA

0

答案是你試圖一次做得太多。你不需要列出ID(我不認爲你這樣做,如果是的話,你需要在最內層的查詢中使用聚合)。我相信這是你真正需要的是什麼(請注意聚集體的所有款項):

select `neighbourhood_id`, 
    `listing_for_sale`, `total_sale_price`/`listing_for_sale` as `avg_sale_price`, 
    `listing_for_rent`, `total_rent_price`/`listing_for_rent` as `avg_rent_price` from 
    (SELECT `neighbourhood_id`, 
     SUM(IF(`c`.`listing_offer` = 1, 1, 0)) as `listing_for_sale`, 
     SUM(IF(`c`.`listing_offer` = 1, `price`, 0)) as `total_sale_price`, 
     SUM(IF(`c`.`listing_offer` = 2, 1, 0)) as `listing_for_rent`, 
     SUM(IF(`c`.`listing_offer` = 2, `price`, 0)) as `total_rent_price` 
    FROM (
     SELECT `n`.`id` AS `neighbourhood_id`, `l`.* 
     FROM `listing` `l` 
     LEFT JOIN `address` `a` ON `l`.`address_id` = `a`.`id` 
     LEFT JOIN `address_neighbourhood` `an` ON `a`.`id` = `an`.`address_id` 
     LEFT JOIN `neighbourhood` `n` ON `an`.`neighbourhood_id` =  `n`.`id` 
     WHERE (`l`.`deleted`=0) 
     AND `n`.`id` IS NOT NULL 
    ) `c` 
    GROUP BY `neighbourhood_id` 
) `d` 
相關問題