Pergunta

Eu tenho uma consulta MySQL em que eu quiser incluir uma lista de ids de outra tabela.No site, as pessoas são capazes de adicionar alguns itens, e as pessoas podem, em seguida, adicionar os itens aos seus favoritos.Eu, basicamente, quer para obter a lista de IDENTIFICAÇÃO de pessoas que têm liked item (isto é um pouco simplificado, mas isso é o que ferve para baixo).

Basicamente, eu faço algo parecido com isto:

SELECT *,
GROUP_CONCAT((SELECT userid FROM favourites WHERE itemid = items.id) SEPARATOR ',') AS idlist
FROM items
WHERE id = $someid

Desta forma, eu seria capaz de mostrar que liked algum item, dividindo o idlist mais tarde, para um array no PHP no meu código, no entanto estou recebendo o seguinte MySQL erro:

1242 - a Subconsulta retorna mais de 1 linha

Eu pensei que era uma espécie de ponto de usar GROUP_CONCAT em vez de, por exemplo, CONCAT?Estou indo sobre isso da maneira errada?


Ok, obrigado pelas respostas até agora, que parece funcionar.No entanto, há um senão.Os itens também são considerados para ser um favorito se ele foi adicionado pelo usuário.Então eu teria uma verificação adicional para verificar se o criador = userid.Alguém pode me ajudar a encontrar um smart (e espero eficiente) maneira de fazer isso?

Obrigado!

Editar:Eu apenas tentei fazer isso:

SELECT [...] LEFT JOIN favourites ON (userid = itemid OR creator = userid)

E idlist é vazio.Observe que, se eu usar INNER JOIN em vez de LEFT JOIN Eu obter um resultado vazio.Embora eu tenho certeza que não são linhas que atendem o requisito.

Foi útil?

Solução

Você não pode variáveis ??de acesso no âmbito exterior em tais consultas (não pode usar items.id lá). Você deve, antes, tentar algo como

SELECT
    items.name,
    items.color,
    CONCAT(favourites.userid) as idlist
FROM
    items
INNER JOIN favourites ON items.id = favourites.itemid
WHERE
    items.id = $someid
GROUP BY
    items.name,
    items.color;

Expanda a lista de campos conforme necessário (nome, cor ...).

Outras dicas

OP quase acertou. GROUP_CONCAT deve ser envolver as colunas na subconsulta e não o subconsulta completo (eu estou descartando o separador porque vírgula é o padrão ):

SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid

Isto irá produzir o resultado desejado e também significa que a resposta aceita é parcialmente errado, porque você pode acessar variáveis ??escopo externo em uma subconsulta.

Eu acho que você pode ter a "userid = itemid" errado, não deveria ser assim:

SELECT ITEMS.id,GROUP_CONCAT(FAVOURITES.UserId) AS IdList
FROM FAVOURITES 
INNER JOIN ITEMS ON (ITEMS.Id = FAVOURITES.ItemId OR FAVOURITES.UserId = ITEMS.Creator)
WHERE ITEMS.Id = $someid
GROUP BY ITEMS.ID

O objetivo da GROUP_CONCAT está correta, mas a subconsulta é desnecessária e causando o problema. Tente isto em vez disso:

SELECT ITEMS.id,GROUP_CONCAT(FAVOURITES.UserId)
FROM FAVOURITES INNER JOIN ITEMS ON ITEMS.Id = FAVOURITES.ItemId
WHERE ITEMS.Id = $someid
GROUP BY ITEMS.ID

Sim, soulmerge a solução é ok.Mas eu precisava de uma consulta onde eu tinha para coletar dados de mais uma criança tabelas, por exemplo:

  • tabela principal: sessões (sessões de apresentação) (uid, nome, ..)
  • 1º filho tabela: eventos com chave session_id (uid, session_uid, data, time_start, time_end)
  • 2ª criança tabela: accessories_needed (laptop, projetor, microfone, etc.) com chave session_id (uid, session_uid, accessory_name)
  • 3ª criança tabela: session_presenters (apresentador pessoas) com chave de session_id (uid, session_uid, presenter_name, endereço...)

Cada Sessão tem mais linhas na criança tabelas as tabelas (mais horários, mais acessórios)

E eu precisava recolher em um conjunto para cada sessão para exibição no minério de linha (alguns deles):

session_id | session_name | date | time_start | time_end | accessories | presenters

Minha solução (depois de muitas horas de experimentos):

SELECT sessions.uid, sessions.name,
    ,(SELECT GROUP_CONCAT( `events`.date SEPARATOR '</li><li>') 
            FROM `events` 
            WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS date
    ,(SELECT GROUP_CONCAT( `events`.time_start SEPARATOR '</li><li>') 
            FROM `events` 
            WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS time_start
    ,(SELECT GROUP_CONCAT( `events`.time_end SEPARATOR '</li><li>') 
            FROM `events` 
            WHERE `events`.session_id = sessions.uid ORDER BY `events`.date) AS time_end
    ,(SELECT GROUP_CONCAT( accessories.name SEPARATOR '</li><li>') 
            FROM accessories 
            WHERE accessories.session_id = sessions.uid ORDER BY accessories.name) AS accessories
    ,(SELECT GROUP_CONCAT( presenters.name SEPARATOR '</li><li>') 
            FROM presenters
            WHERE presenters.session_id = sessions.uid ORDER BY presenters.name) AS presenters

    FROM sessions

Assim, nenhuma ASSOCIAÇÃO ou GRUPO, se necessário.Outra coisa útil para exibir dados amigável (quando "ecoando" deles):

  • você pode moldar os eventos.data, time_start, time_end, etc."<UL><LI> ...</LI></UL>"assim, a "<LI></LI>"usado como separador na consulta irá separar os resultados em itens de lista.

Espero que isso ajude alguém.Saúde!

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