Eu li muitos tópicos sobre como obter apenas a primeira linha de uma junção esquerda, mas, por algum motivo, isso não funciona para mim.
Aqui está minha estrutura (simplificada, é claro)
Feeds
id | title | content
----------------------
1 | Feed 1 | ...
Artistas
artist_id | artist_name
-----------------------
1 | Artist 1
2 | Artist 2
feeds_artists
rel_id | artist_id | feed_id
----------------------------
1 | 1 | 1
2 | 2 | 1
...
Agora eu quero pegar os artigos e juntar-me apenas ao primeiro Artist e pensei em algo assim:
SELECT *
FROM feeds
LEFT JOIN feeds_artists ON wp_feeds.id = (
SELECT feeds_artists.feed_id FROM feeds_artists
WHERE feeds_artists.feed_id = feeds.id
LIMIT 1
)
WHERE feeds.id = '13815'
apenas para obter apenas a primeira linha dos feeds_artists, mas isso já não funciona.
Não posso usar TOP
por causa do meu banco de dados e não consigo agrupar os resultados, feeds_artists.artist_id
pois preciso classificá-los por data (obtive resultados agrupando-os dessa maneira, mas os resultados não são os mais recentes)
Tentei algo com OUTER APPLY também - sem sucesso também. Para ser honesto, não consigo imaginar o que está acontecendo nessas linhas - provavelmente a maior razão pela qual não consigo fazer isso funcionar.
SOLUÇÃO:
SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
SELECT artist_id
FROM feeds_artists fa
WHERE fa.feed_id = f.id
LIMIT 1
)
WHERE f.id = '13815'
Respostas:
Se você puder supor que os IDs de artistas aumentam com o tempo,
MIN(artist_id)
será o mais antigo.Então, tente algo assim (não testado ...)
fonte
Versão sem subseleção:
fonte
A resposta do @Matt Dodges me colocou no caminho certo. Mais uma vez obrigado por todas as respostas, o que ajudou muitos caras nesse meio tempo. Funcionou assim:
fonte
f.id
condição.Eu usei outra coisa (acho melhor ...) e quero compartilhá-la:
Eu criei uma VIEW que possui uma cláusula "group"
Quero dizer ainda que acho que precisamos fazer essa solução, porque fizemos algo errado na análise ... pelo menos no meu caso ... mas às vezes é mais barato fazer isso do que redesenhar tudo ...
Espero que ajude!
fonte
country_code
, issoGROUP BY
é impróprio. VejaONLY_FULL_GROUP_BY
.WITH x AS (
cláusula?com base em várias respostas aqui, encontrei algo que funcionou para mim e queria generalizar e explicar o que estava acontecendo.
converter:
para:
a condição que conecta t1 e t2 é movida da
ON
e para a consulta internaWHERE
. oMIN(primary key)
ouLIMIT 1
garante que apenas 1 linha seja retornada pela consulta interna.depois de selecionar uma linha específica, precisamos dizer
ON
qual é a linha. é por isso queON
está comparando a chave primária da tabela juntada.você pode jogar com a consulta interna (ou seja, ordem + limite), mas ela deve retornar uma chave primária da linha desejada que informará a
ON
linha exata para ingressar.fonte
LIMIT
ou apenasMIN
. aON
condição deve estar na chave primária da tabela unida para evitar impacto no desempenho.Eu quero dar uma resposta mais generalizada . Um que lida com qualquer caso quando você deseja selecionar apenas o primeiro item em um LEFT JOIN .
Você pode usar uma subconsulta que GROUP_CONCATS o que você deseja (classificada também!), Depois dividir o resultado do GROUP_CONCAT e pegar apenas o primeiro item, assim ...
Como temos DESC como nossa opção ORDER BY , isso retornará um ID de pessoa para alguém como "Zack". Se quiséssemos alguém com o nome "Andy", mudaríamos ORDER BY FirstName DESC para ORDER BY FirstName ASC .
Isso é ágil, pois coloca o poder de encomendar totalmente em suas mãos. Mas, após muitos testes, ele não será dimensionado bem em uma situação com muitos usuários e muitos dados.
No entanto, é útil na execução de relatórios com muitos dados para o administrador.
fonte
GROUP_CONCAT
truque é bom, desde que o número de valores seja limitado. O limite padrão é 1024 caracteres.