mysql 서브쿼리 검색 후 일치하는 레코드만 출력하려 합니다. 0 7 501

by 칠복이 [MySQL] [2021.08.03 23:06:23]


안녕하세요~ 질문좀 드릴께요.

SELECT * from 
(
  SELECT order_id, goods, (select group_concat(goods) from shop_ordergoods where orderid=g1.orderid) AS g2 
  FROM 
  shop_ordergoods AS g1 
  where 
  goods IN (3011, 3022, 3041)
) AS C;

위의 쿼리를 실행하면 아래의 테이블과  같이 나오는데 하나의 order_id의 g2의 값이  goods IN (3011, 3022, 3041) <-- 이 숫자들만 포함된 레코드만 출력하려고 하는데요. 예를 들면 33333-22222의 order_id의 g2에는 3033과 4011이 있기때문에 이 레코드를 제외하고 출력하려고 하는데 어떻게 하면 될까요? order_id는 중복이 되기때문에 group_concat하였습니다.

order_id goods g2
11111-22222 3011 3011, 3022
33333-22222 3022 3022, 3033, 4011
44444-22222 3041 3041, 3011

 

by pajama [2021.08.04 09:40:25]

먼저 원하시는 값을 추출해서 group_concat 사용하시면 되지 않을까요?

 

SELECT order_id, goods, group_concat(goods) g2
FROM (
  SELECT order_id, goods
  FROM
  shop_ordergoods AS g1 
  where
  goods IN (3011, 3022, 3041)
  
) C
group by order_id
;

 


by 칠복이 [2021.08.04 10:08:36]

답변 감사합니다. 그런데 위의 쿼리는 레코드 총 수가 같게 나옵니다. 결과 값에서 3011, 3022, 3041 외의 값만 제외하고 보여주고 있습니다.
제가 하려고 하는것은 g2가 3011, 3022, 3041 외에의 값을 가진 레코드는 출력하지 않는 것입니다.


by 칠복이 [2021.08.04 10:13:31]

 

 

 

                                                              g2

"7920195"    "11111111-425276"    "3078"    "3078"
"7916239"    "11111111-3023"    "3079"    "4567,3079"<---(3011, 3022, 3041 외에 값을 가지므로 출력되서는 안됨)
"7915513"    "11111111-628295"    "3077"    "4596,4596,3077,3077,3077"
"7915830"    "11111111-676251"    "3078"    "3078,4692"
"7915829"    "11111111-630127"    "3080"    "4659,4555,4567,3143,3080"
"7915852"    "11111111-676141"    "3077"    "3077,3077,3077"
"7916006"    "11111111-122796"    "3079"    "3079"
"7917123"    "11111111-675356"    "3077"    "4692,4581,3077"
"7917114"    "11111111-18548"    "3078"    "3078"
"7918256"    "11111111-673965"    "3077"    "3077,3077"


by 마농 [2021.08.04 10:24:15]
-- 출력결과가 어떻게 나와야 하나요?
-- 1. 한 ID 당 한줄만 나오면 되나요?
-- 2. 아니면 여러줄 나와야 하나요?
 
-- 1. order_id 하나당 한줄로 집계하여 출력 --
SELECT order_id
     , GROUP_CONCAT(goods) goods
  FROM shop_ordergoods
 GROUP BY orderid
HAVING COUNT(CASE WHEN goods NOT IN (3011, 3022, 3041) THEN 1 END) = 0
;
 
-- 2.1. 집계 없이 그대로 출력 : Exists 서브쿼리 조건 --
SELECT order_id
     , goods
  FROM shop_ordergoods g1
 WHERE goods IN (3011, 3022, 3041)
   AND NOT EXISTS (SELECT 1
                     FROM shop_ordergoods g2
                    WHERE g2.order_id = g1.order_id
                      AND g2.goods NOT IN (3011, 3022, 3041)
                   )
;

-- 2.2. 집계 없이 그대로 출력 : 분석함수 이용 --
SELECT *
  FROM (SELECT order_id
             , goods
             , COUNT(CASE WHEN goods NOT IN (3011, 3022, 3041) THEN 1 END)
               OVER(PARTITION BY order_id) cnt
          FROM shop_ordergoods
        ) c
 WHERE cnt = 0
;

 


by 칠복이 [2021.08.04 14:24:21]

답변 주셔서 감사합니다. mysql 5.5.62버전인데 해당 쿼리를 해보니 오류가 발생합니다.

출력결과는 아래의 표에서  빨간 글씨 부분에 g2 컬럼이 goods IN (3011, 3022, 3041) 외에의 값인 4011포함되므로 order_id 33333-22222빼고 출력이 되면 됩니다.

 

order_id goods g2
11111-22222 3011 3011, 3022
33333-22222 3022 3022, 3033, 4011
44444-22222 3041 3041, 3011

by 마농 [2021.08.04 14:40:02]

분석함수는 8 버전에서 수행됩니다.
분석함수를 뺀 나머지 구문은 적용 가능할 텐데요?
혹시 case 문이 안되면 if 문으로 바꿔보세요.


by 칠복이 [2021.08.04 16:13:31]

감사합니다.

-- 2.1. 집계 없이 그대로 출력 : Exists 서브쿼리 조건 --

SELECT order_id

     , goods

  FROM shop_ordergoods g1

 WHERE goods IN (3011, 3022, 3041)

   AND NOT EXISTS (SELECT 1

                     FROM shop_ordergoods g2

                    WHERE g2.order_id = g1.order_id

                      AND g2.goods NOT IN (3011, 3022, 3041)

                   )

;

로하니까 잘되네요 ^^

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입