Subconsse com vários resultados combinados em um único campo?
-
27-09-2019 - |
Pergunta
Suponha que eu tenha essas tabelas, das quais preciso exibir resultados de pesquisa em um navegador:
Table: Containers
id | name
1 Big Box
2 Grocery Bag
3 Envelope
4 Zip Lock
Table: Sale
id | date | containerid
1 20100101 1
2 20100102 2
3 20091201 3
4 20091115 4
Table: Items
id | name | saleid
1 Barbie Doll 1
2 Coin 3
3 Pop-Top 4
4 Barbie Doll 2
5 Coin 4
Eu preciso de saída que se parece com o seguinte:
itemid itemname saleids saledates containerids containertypes
1 Barbie Doll 1,2 20100101,20100102 1,2 Big Box, Grocery Bag
2 Coin 3,4 20091201,20091115 3,4 Envelope, Zip Lock
3 Pop-Top 4 20091115 4 Zip Lock
A parte importante é que cada tipo de item obtém apenas um registro/linha no retorno na tela. Consegui isso no passado retornando várias linhas do mesmo item e usando uma linguagem de script para limitar a saída. No entanto, isso torna a interface do usuário excessivamente complicada e loopy. Então, espero poder fazer com que o banco de dados cuspir apenas tantos registros quanto linhas para exibir.
Este exemplo pode ser um pouco extremo devido às duas junções necessárias para chegar ao contêiner do item (através da tabela de venda).
Eu ficaria feliz por apenas um exemplo de consulta que gera o seguinte:
itemid itemname saleids saledates
1 Barbie Doll 1,2 20100101,20100102
2 Coin 3,4 20091201,20091115
3 Pop-Top 4 20091115
Só posso devolver um único resultado em uma subconeração, então não tenho certeza de como fazer isso.
Solução
Supondo que você esteja usando o MySQL (das quatro perguntas que você tem, apenas uma é marcada como MySQL), o Função group_concat é o que você procura:
SELECT i.name AS itemname,
GROUP_CONCAT(s.id ORDER BY s.id) AS salesids,
GROUP_CONCAT(s.date ORDER BY s.date) AS salesdates,
GROUP_CONCAT(s.containerid ORDER BY s.containerid) AS containerids,
GROUP_CONCAT(c.name ORDER BY c.name) AS containertypes
FROM ITEMS i
JOIN SALE s ON s.id = i.salesid
JOIN CONTAINERS c ON c.id = s.containerid
GROUP BY i.name
Se você deseja itens que possam não ter links para as tabelas de vendas e/ou contêineres - adicione "esquerda" na frente da "junção".