2011-12-07 23 views
5

Chcę otrzymywać nazwę nieruchomości oraz liczbę jednostek i liczbę odrysowań. Mam to zapytanie:Double LEFT DOŁĄCZ

SELECT 
    `property`.`property_name`, 
    COUNT(unit_id) AS `units_count`, 
    COUNT(special_id) AS `specials_count` 
FROM `property` 
    LEFT JOIN `property_unit` ON unit_property_id = property_id 
    LEFT JOIN `property_special` ON special_property_id = property_id 
WHERE (property_id = '1') 
GROUP BY `property_id` 
ORDER BY `property_name` ASC 

Ale nie działa poprawnie. Jeśli mam jeden z tych lewej dołącza - to ok, ale jeśli mam dwie, otrzymuję ten wynik:

Ilość
["property_name"] => string(11) "Rivers Edge" 
["units_count"] => string(1) "2" 
["specials_count"] => string(1) "2" 

Specials jest 2 i units_count wynosi 2, ale liczba jednostek jest naprawdę „1”. Jak mogę uzyskać dla niego poprawne liczby?

PS: dla tych, którzy wiedzą, Zend Framework:

$select->setIntegrityCheck(FALSE) 
    ->from(
     'property', 
     array(
      'property_name', 
     ) 
    ) 
    ->joinLeft(
     'property_unit', 
     'unit_property_id = property_id', 
     array(
      'units_count' => 'COUNT(unit_id)' 
     ) 
    ) 
    ->joinLeft(
     'property_special', 
     'special_property_id = property_id', 
     array(
      'specials_count' => 'COUNT(special_id)' 
     ) 
    ) 
    ->group('property_id') 
    ->order('property_name'); 
+0

Czy unikalne klucze unit_id i special_id znajdują się w tabelach property_unit i property_special? –

+0

@ Mark Bannister Tak –

Odpowiedz

9

Spróbuj tego:

SELECT 
    `property`.`property_name`, 
    COUNT(distinct unit_id) AS `units_count`, 
    COUNT(distinct special_id) AS `specials_count` 
FROM `property` 
    LEFT JOIN `property_unit` ON unit_property_id = property_id 
    LEFT JOIN `property_special` ON special_property_id = property_id 
WHERE (property_id = '1') 
GROUP BY `property_id` 
ORDER BY `property_name` ASC 

EDIT:

Nie powinieneś zawsze używaj różnych - w takim przypadku jest to właściwa opcja.

select count(fieldname) zwraca liczbę razy, gdy nazwa pola nie jest pusta; select count(distinct fieldname) zwraca liczbę odrębnych wartości nazwy pola.

W pierwotnym zapytaniu właściwości property_unit i property_special nie są połączone ze sobą, tylko dla właściwości - tak dla pojedynczej właściwości, która ma 5 jednostek i 7 specjalnych, zwróconych zostanie 35 wierszy; w związku z tym count(unit_id) i count(special_id) powrócą 35. Ponieważ istnieje 5 odrębnych wartości unit_id i 7 różnych wartości special_id (ponieważ te pola jednoznacznie identyfikują swoje rekordy), count(distinct ...) zwraca prawidłowe wartości w tych okolicznościach.

+0

Bardzo dziękuję, to działa! Ale nie mogę zrozumieć, dlaczego powinienem zawsze używać DISTINCT .. –

+0

@DmitryTeplyakov: zobacz zaktualizowaną odpowiedź. –

+0

Dziękuję bardzo! To świetne wyjaśnienie! –

1

Twój SQL powinno być coś takiego:

 
SELECT 
    `property`.`property_name`, 
    COUNT(property_unit.unit_id) AS `units_count`, 
    COUNT(property_special.special_id) AS `specials_count` 
FROM `property` 
    LEFT JOIN `property_unit` ON (property_unit.unit_property_id = property.property_id) 
    LEFT JOIN `property_special` ON (property_special.special_property_id = property.property_id) 
WHERE (property.property_id = '1') 
GROUP BY `property.property_id` 
ORDER BY `property.property_name` ASC 

+0

To samo zapytanie. unit_id i special_id są unikalne –