Agrupar por, COUNT (*) e JOIN

1

Ao executar o SQL abaixo, qualquer placemark_types.id que não tenha uma correspondência de ID na tabela de marcadores não retornará nada nos resultados. Eu estou tentando pelo menos obter um type_count de 0 de volta onde não há registros correspondentes em marcadores.

Portanto, se eu tiver um placemark_types.name de 'Aviso' e não houver nenhuma tabela 'Aviso na tabela de marcadores, id gostaria de obter as colunas | 0 | 'Warning'|

SELECT COUNT( * ) AS type_count, placemark_types.name
FROM  'placemark_types' 
JOIN placemarks ON placemark_types.id = placemarks.type_id
WHERE placemark_types.parent_id =0
GROUP BY placemark_types.id
    
por Rob 30.11.2012 / 18:24

2 respostas

6

O MySQL, por padrão, executa um INNER JOIN , onde apenas as linhas com um registro em ambas as tabelas são retornadas.

Você pode fazer um LEFT JOIN ou RIGHT JOIN para dizer ao MySQL para retornar um lado da união, mesmo que o outro lado esteja vazio. Nesta situação, você desejaria um RIGHT JOIN .

    
por 30.11.2012 / 18:27
1

É melhor sempre especificar o tipo de junção que você está fazendo. Por padrão, ele está usando uma junção interna. Uma junção interna mostrará apenas itens que possuem uma correspondência em ambas as tabelas. No seu exemplo, você deseja que todos os registros retornados de placemark_types e zero-para-muitos dos registros da tabela de marcadores correspondam.

Para isso, basta usar uma junção à esquerda, como mostrado abaixo. A junção à esquerda sempre retorna todos os registros do lado esquerdo (placemark_types) e somente os registros correspondentes do lado direito (marcadores). Em seguida, vamos nos livrar do COUNT(*) e usar COUNT (placemarks.type_id), porque não queremos contar todas as linhas, apenas aquelas com correspondências na tabela de marcadores. Senão você ganharia 1 mesmo quando o seu zero correspondesse porque ainda estaria contando os placemark_types.

SELECT COUNT(placemarks.type_id) AS type_count, placemark_types.name
FROM  placemark_types
LEFT JOIN placemarks ON placemark_types.id = placemarks.type_id
WHERE placemark_types.parent_id = 0
GROUP BY placemark_types.id

Para entender melhor, execute a consulta sem o GROUP BY . Você verá que mesmo quando não houver entradas na tabela de marcadores, você receberá os campos da tabela placemark_types e os valores nulos dos campos de marcadores. Como o COUNT(placemarks.type_id) não contará nulos, isso fornecerá o número correto.

    
por 20.12.2012 / 21:58

Tags