sourcecode

MySQL 서브쿼리에서 GROUP_CONCAT 사용

copyscript 2023. 1. 20. 16:16
반응형

MySQL 서브쿼리에서 GROUP_CONCAT 사용

MySQL 쿼리에서 다른 테이블의 ID 목록을 포함하려고 합니다.웹사이트에서 사람들은 특정 아이템을 추가할 수 있고, 그 아이템을 즐겨찾기에 추가할 수 있다.기본적으로 그 아이템을 좋아하는 사람의 아이디를 입수하고 싶습니다(이것은 조금 간결하지만, 요점은 이것입니다).

기본적으로 다음과 같은 작업을 수행합니다.

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

이렇게 하면 나중에 idlist를 내 코드의 PHP 어레이로 분할하여 누가 어떤 아이템을 선호하는지 알 수 있는데, 다음과 같은 MySQL 오류가 발생합니다.

1242 - 서브쿼리가 1개 이상의 행을 반환함

난 그게 바로 내가 원하는 걸 쓰는 이유라고 생각했어.GROUP_CONCAT예를 들면,CONCAT제가 잘못된 방향으로 가고 있는 건가요?


네, 지금까지 답변 감사합니다. 효과가 있는 것 같네요.하지만, 한가지 단점이 있다.사용자가 추가한 아이템도 즐겨찾기로 간주됩니다.그래서 크리에이터 = userid인지 확인하기 위해 추가 확인이 필요합니다.누군가 스마트한(그리고 효율적인) 방법을 생각해 낼 수 있도록 도와줄 수 있나요?

감사해요!

편집: 방금 시도했습니다.

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

ID 목록이 비어 있습니다.주의해 주세요.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

네, 소울머지의 솔루션은 괜찮습니다.하지만 다음과 같은 더 많은 하위 테이블에서 데이터를 수집해야 하는 쿼리가 필요했습니다.

  • 메인 테이블: 세션(프레젠테이션세션)(uid, 이름 등)
  • 첫 번째 자녀 테이블: session_id를 가진 이벤트(uid, session_uid, date, time_start, time_end)
  • 두 번째 자녀 테이블: 키 session_id(uid, session_uid, accentory_name)를 가진 악세사리_needed(필수, 프로젝터, 마이크 등)
  • 세 번째 자녀 테이블: session_id 키(uid, session_uid, present_name, address...)를 가진 session_presenters(세컨더리 사용자)

모든 세션의 하위 테이블에는 더 많은 행이 있습니다(시간 스케줄이 더 많고 액세서리가 더 많습니다).

또한 모든 세션에 대해 하나의 컬렉션으로 수집해야 했습니다(일부 세션).

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

가입이나 GROUP BY는 필요 없습니다.데이터를 쉽게 표시할 수 있는 또 다른 유용한 기능(메아리 처리 시):

  • events.date, time_start, time_end 등을 "<UL>..."</LI></UL>"로 랩할 수 있으므로 쿼리에서 구분자로 사용되는 "<LI></LI>"는 결과를 목록 항목으로 구분합니다.

이게 도움이 됐으면 좋겠어요.건배!

언급URL : https://stackoverflow.com/questions/377850/using-group-concat-on-subquery-in-mysql

반응형