簡體   English   中英

在MySQL中的子查詢上使用GROUP_CONCAT

[英]Using GROUP_CONCAT on subquery in MySQL

我有一個MySQL查詢,我想在其中包含另一個表中的ID列表。 在網站上,人們可以添加某些項目,然后人們可以將這些項目添加到他們的收藏夾中。 我基本上想要獲得那些喜歡該項目的人的ID列表(這有點簡化,但這就是它歸結為)。

基本上,我做這樣的事情:

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

通過這種方式,我可以通過在我的代碼中進一步將id列表轉換為PHP中的數組來顯示誰喜歡某個項目,但是我收到以下MySQL錯誤:

1242 - 子查詢返回超過1行

我認為這有點使用GROUP_CONCAT而不是例如CONCAT 我是以錯誤的方式來做這件事的嗎?


好的,感謝到目前為止的答案,這似乎有效。 然而,有一個問題。 如果該項目由該用戶添加,則該項目也被視為最受歡迎。 所以我需要額外的檢查以檢查creator = userid。 有人可以幫我提出一個聰明(並希望有效)的方法嗎?

謝謝!

編輯:我只是試圖這樣做:

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

idlist是空的。 請注意,如果我使用INNER JOIN而不是LEFT JOIN我會得到一個空結果。 即使我確信有些行符合ON要求。

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

這將產生所需的結果,也意味着接受的答案部分錯誤,因為您可以訪問子查詢中的外部范圍變量。

您無法在此類查詢中訪問外部作用域中的變量(不能使用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;

根據需要展開字段列表(名稱,顏色......)。

我認為你可能有“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

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

是的,soulmerge的解決方案還可以。 但我需要一個查詢,我必須從更多的子表中收集數據,例如:

  • 主表: 會話 (演示會話)(uid,name,..)
  • 第一個子表:具有關鍵session_id的事件 (uid,session_uid,date,time_start,time_end)
  • 第二個子表: accessories_needed (筆記本電腦,投影儀,麥克風等),帶有密鑰session_id(uid,session_uid,accessory_name)
  • 第3個子表:具有密鑰session_id的session_presenters (演示者人員)(uid,session_uid,presenter_name,地址...)

每個會話在子表表中有更多行(更多時間表,更多附件)

我需要在每個會話中收集一個集合以顯示在礦石行(其中一些):

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。 顯示數據友好的另一個有用的東西(當“回顯”它們時):

  • 你可以將events.date,time_start,time_end等包裝在“<UL> <LI> ... </ LI> </ UL>”中,這樣​​“<LI> </ LI>”在查詢中用作分隔符將列表項中的結果分開。

我希望這可以幫助別人。 干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM