Pergunta

Eu tenho três tabelas:página, anexo, anexo de página

Eu tenho dados como este:

page
ID    NAME
1     first page
2     second page
3     third page
4     fourth page

attachment
ID    NAME
1     foo.word
2     test.xsl
3     mm.ppt

page-attachment
ID    PAGE-ID   ATTACHMENT-ID
1     2         1
2     2         2
3     3         3

Gostaria de obter o número de anexos por página também quando esse número é 0.Eu tentei com:

select page.name, count(page-attachment.id) as attachmentsnumber 
from page 
    inner join page-attachment on page.id=page-id 
group by page.id

Estou recebendo esta saída:

NAME        ATTACHMENTSNUMBER
second page  2
third page   1

Eu gostaria de obter esta saída:

NAME        ATTACHMENTSNUMBER
first page   0
second page  2
third page   1
fourth page  0

Como faço para obter a parte 0?

Foi útil?

Solução

Altere sua "junção interna" para "junção externa esquerda", que significa "obtenha todas as linhas à esquerda da junção, mesmo que não haja uma linha correspondente à direita".

select page.name, count(page-attachment.id) as attachmentsnumber 
from page 
    left outer join page-attachment on page.id=page-id 
group by page.name

Outras dicas

Aqui está outra solução usando subconsulta.

SELECT
  p.name,
  (
    SELECT COUNT(*) FROM [page-attachment] pa
    WHERE pa.[PAGE-ID] = p.id
  ) as attachmentsnumber
FROM page p

Dependendo do banco de dados, para velocidade, você pode usar o comando UNION.

O SQL é mais longo, mas, dependendo do banco de dados, agiliza separando "contar coisas que estão lá" e "contar coisas que não estão lá".

(
select page.name, count(page-attachment.id) as attachmentsnumber 
from page 
inner join page-attachment on page.id=page-id 
group by page.id
)
UNION
(
select page.name, 0 as attachmentsnumber 
from page
where page.id not in (
    select page-id from page-attachment)
)   

O banco de dados para o qual preciso desta solução tem 20 páginas em mais de um milhão de anexos.O UNION fez com que ele fosse executado em 13 segundos, em vez de tanto tempo que fiquei entediado e tentei de outra maneira (algo acima de 60 segundos antes de eliminar os métodos de junção externa e subconsulta).

Você deseja uma junção à esquerda, em vez de uma junção interna, pois isso permite que os registros não existam.

A junção ESQUERDA é sua amiga.Para saber mais sobre os diferentes tipos de junção, consulte http://en.wikipedia.org/wiki/Join_(SQL)

Usa isto:

SELECT p.name,(
    SELECT COUNT(*) FROM [page-attachment] pa WHERE pa.[PAGE-ID] = p.id) as attachmentsnumber
FROM page p
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top