SQL: Declaração para mostrar um registro filho por pai em um relacionamento um-para-muitos

StackOverflow https://stackoverflow.com/questions/896561

  •  23-08-2019
  •  | 
  •  

Pergunta

Eu tenho 2 tabelas, uma tabela de produtos e uma tabela de imagem. Os produtos podem ter uma imagem mais de 1 por registro. Eu preciso de uma instrução SQL que irá listar imagem 1 por produto, em vez de todas as imagens por produto.

A reduzida exemplo do meu esforço atual é:

SELECT Product.RefCode, Img.ImgPath
FROM Product INNER JOIN (
    SELECT ProductImg.ImgPath, ProductImg.PrdFK
    FROM ProductImg 
    LIMIT 0,1) AS Img ON Product.PrdID = Img.PrdFK;

O exemplo acima retorna 0 resultados, no entanto, se eu remover o limite de 0,1 do Sub SELECIONE posso obter uma lista completa de todos os produtos e todas as imagens.

Eu só quero um registro de imagem por registro do produto a ser devolvido.


Eu tenho revisto o código "um programador" para MySQL e funciona bem.

SELECT Product.RefCode, 
        (Select ProductImg.ImgPath
         From ProductImg
         Where Product.PrdID = Img.PrdFK LIMIT 0,1) AS ImgPath
FROM Products

Por alguma razão quando se tenta solução "de Bill Karwin", que enviou a carga do servidor por um longo tempo.

Foi útil?

Solução

Isso deve funcionar:

SELECT Product.RefCode,
       (Select Img.ImgPath
        From ProductImg
        Where Product.PrdID = Img.PrdFK LIMIT 0,1) As ImgPath
FROM Product

Se você tem uma maneira de determinar qual imagem deve o seleto retorno, então você pode adicionar um onde e talvez um ORDER BY na sub-selecionar.

No exemplo a seguir, nós vamos chegar apenas a mais recente das imagens ativos.

SELECT Product.RefCode,
       (Select Img.ImgPath
        From ProductImg
        Where Product.PrdID = Img.PrdFK
          And IsActive = 1
        Order By EntryDate Desc LIMIT 0,1) As ImgPath
FROM Product

Editado e corrigido 'Top 1' para 'Limite de 0,1'.

Outras dicas

MySQL tem alguma flexibilidade aqui. Você pode usar GROUP BY para restringir o resultado para uma linha por produto, e, em seguida, o MySQL irá escolher qual imagem arbitrariamente. Na prática, ela tende a ser a imagem que está armazenada fisicamente pela primeira vez no banco de dados, mas você não tem nenhum controle sobre isso.

SELECT p.RefCode, i.ImgPath
FROM Product p INNER JOIN ProductImg i 
  ON (p.PrdID = i.PrdFK)
GROUP BY p.PrdID;

Se você quer 1 específica imagem por produto, existem maneiras de fazer isso também. Você precisa incluir isso em seus requisitos. : -)

Se você tem uma coluna de identificação na mesa de Imagem, isso deve funcionar (não importa o que o produto SQL ou versão) -

   SELECT
            p.RefCode,
            i1.ImgPath
    FROM
            Product p
    INNER JOIN
            ProductImg i1 ON p.PrdId = i1.PrdFk
    LEFT JOIN
            ProductImg i2 ON i1.PrdId = i2.PrdId
            AND i1.ImgId < i2.ImgId
    WHERE
            i2.ImgId IS NULL

O que você precisa é uma bandeira na mesa da imagem para especificar se é a principal imagem a ser exibida. Há maneiras de puxar uma imagem arbitrária, mas acho que seria melhor para se certificar de que você puxa a imagem correta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top