別のテーブルのIDのリストを含めるMySQLクエリがあります。 Webサイトでは、人々は特定のアイテムを追加でき、人々はそれらのアイテムをお気に入りに追加できます。私は基本的に、そのアイテムを気に入った人のIDのリストを取得したいと思います(これは少し簡略化されていますが、これは要するにそれです)。
基本的に、私はこのようなことをします:
SELECT *,
GROUP_CONCAT((SELECT userid FROM favourites WHERE itemid = items.id) SEPARATOR ',') AS idlist
FROM items
WHERE id = $someid
このように、後でコードのPHPでidlistを配列に分割することで、アイテムをお気に入りに追加したユーザーを表示できますが、次のMySQLエラーが発生しています。
1242-サブクエリは複数の行を返します
これは、たとえばCONCAT
?の代わりにGROUP_CONCAT
を使用することのポイントのようなものだと思いました。私はこれについて間違った方法で行っていますか?
OK、これまでの回答に感謝します、それはうまくいくようです。ただし、キャッチがあります。アイテムは、そのユーザーによって追加された場合もお気に入りであると見なされます。したがって、creator = useridであるかどうかを確認するには、追加のチェックが必要になります。誰かが私にこれを行うためのスマートな(そしてうまくいけば効率的な)方法を思い付くのを助けることができますか?
ありがとうございました!
編集:私はこれをやろうとしました:
SELECT [...] LEFT JOIN favourites ON (userid = itemid OR creator = userid)
idlistは空です。 INNER JOIN
の代わりにLEFT JOIN
を使用すると、空の結果が得られることに注意してください。 ON要件を満たす行があると確信していますが。
このようなクエリでは外部スコープの変数にアクセスできません(items.id
は使用できません)。むしろ何かを試してみてください
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;
必要に応じてフィールドのリストを展開します(名前、色...)。
OPはほぼ正しく設定しました。 GROUP_CONCAT
は、 完全なサブクエリ ではなく、サブクエリの列をラップする必要があります(コンマがデフォルトであるため、セパレータを無視しています)。
SELECT i.*,
(SELECT GROUP_CONCAT(userid) FROM favourites f WHERE f.itemid = i.id) AS idlist
FROM items i
WHERE i.id = $someid
これにより、目的の結果が得られます。また、サブクエリで外部スコープ変数にアクセスできるため、受け入れられた回答が部分的に間違っていることも意味します。
「userid = itemid」が間違っている可能性があると思います。次のようにすべきではありません。
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
はい、soulmergeのソリューションは大丈夫です。しかし、より多くの子テーブルからデータを収集しなければならないクエリが必要でした。たとえば:
すべてのセッションには、子テーブルのテーブルにさらに行があります(より多くのタイムスケジュール、より多くのアクセサリ)
そして、私はすべてのセッションで1つのコレクションに収集して鉱石列に表示する必要がありました(そのうちのいくつか):
session_id | session_name | date | time_start | time_end | accessories | presenters
私の解決策(何時間もの実験の後):
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
したがって、JOINやGROUP BYは必要ありません。データをわかりやすく表示する別の便利な機能(「エコー」する場合):
これが誰かの助けになることを願っています。乾杯!
GROUP_CONCATの目的は正しいですが、サブクエリは不要であり、問題を引き起こしています。代わりにこれを試してください:
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