Почему мой оператор SQL считает разные поля из разных таблиц в одном операторе SQL? - PullRequest
0 голосов
/ 13 мая 2009

У меня SQL-запрос:

SELECT 
    e.name as estate_name 
    , g.name as governing_body
    , count(s.id) as total_stands 
    , count(sp.id) as service_providers 
FROM estates e 
    LEFT JOIN governing_bodies    
        ON e.governing_body_id = g.id 
    LEFT JOIN stands s 
        ON s.estate_id = e.id 
    LEFT JOIN services sp 
        ON sp.estate_id = e.id 
GROUP BY e.id

Кажется, мои счета умножаются друг на друга. Если мой первый счет равен 3, а второй - 10, результаты в полях service_providers и total_stands будут равны 30.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 13 мая 2009

Как насчет изменения конструкций COUNT(blah) на COUNT(DISTINCT blah)?

1 голос
/ 13 мая 2009

Счетчик () отображает количество строк, найденных для вашей группы. Так как вы группируете по имуществу, оно будет подсчитывать количество рядов, которые вы присоединяете к имуществу. Соединения умножат количество строк, поэтому 3 x 10 = 30 звучит как правильный счет. Запустите запрос без GROUP BY, чтобы увидеть, что происходит.

Один из способов исправить это будет выглядеть так:

SELECT 
    e.name as estate_name, 
    g.name as governing_body, 
    (select count(*) from stands s where s.estate_id = e.id) as stands,
    (select count(*) from services sp where sp.estate_id = e.id) as services
FROM estates e
LEFT JOIN governing_bodies g on e.governing_body_id = g.id 

Написание информативного ответа Алекса Мартелли:

SELECT 
    e.name as estate_name 
    , g.name as governing_body
    , count(distinct s.id) as total_stands 
    , count(distinct sp.id) as service_providers 
FROM estates e 
    LEFT JOIN governing_bodies    
        ON e.governing_body_id = g.id 
    LEFT JOIN stands s 
        ON s.estate_id = e.id 
    LEFT JOIN services sp 
        ON sp.estate_id = e.id 
GROUP BY e.id, g.name

Или, как более сложная альтернатива с синтаксисом JOIN:

SELECT 
    e.name as estate_name, 
    g.name as governing_body, 
    IsNull(stand_count.total,0) as stand_count,
    IsNull(service_count.total,0) as service_count
FROM estates e
LEFT JOIN governing_bodies g on e.governing_body_id = g.id
LEFT JOIN (
   select estate_id, total = count(*) from stands group by estate_id
) stand_count on stand_count.estate_id = e.id
LEFT JOIN (
    select estate_id, total = count(*) from services group by estate_id
) service_count on service_count.estate_id = e.id
GROUP BY
    e.name,
    g.name,
    IsNull(stand_count.total,0),
    IsNull(service_count.total,0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...