Development Tip

여러 자식 행을 하나의 행으로 결합 MYSQL

yourdevel 2020. 11. 17. 21:09
반응형

여러 자식 행을 하나의 행으로 결합 MYSQL


미리 감사드립니다. 나는 그것을 얻을 수없는 것 같습니다!

두 개의 테이블이 있습니다

Ordered_Item

아이디 | 상품명
1 | 피자
2 | 스트롬 볼리

Ordered_Options

Ordered_Item_ID | Option_Number | 
        1 43 ​​페퍼로니
        1 44 엑스트라 치즈
        2 44 엑스트라 치즈

출력하고자하는 것은 mysql 쿼리가이 효과에 대한 것입니다.

산출

아이디 | Item_Name | Option_1 | Option_2
1 피자 페퍼로니 엑스트라 치즈
2 스트롬 볼리 널 엑스트라 치즈

나는 구문 오류로 끝나는 수많은 옵션을 시도했지만 group_concat을 시도했지만 실제로는 내가 찾고있는 것이 아닙니다. 나는 시작이라고 생각하는 것에 대한 조잡한 예가 아래에 있습니다. 매번 같은 순서로 옵션이 필요합니다. 그리고 정보가 수집되는 프로그램에서는 그러한 일이 발생하는지 신뢰할 수있는 방법이 없습니다. 옵션 번호에 따라 연결되도록 할 수 있습니까? 또한 나는 5 개 이상의 옵션을 가질 수 없다는 것을 알고 있으므로 정적 솔루션이 작동 할 것입니다.

Select Ordered_Items.ID,
    Ordered_Items.Item_Name,
FROM Ordered_Items
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 43) as Option_1 
        ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID
    JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 44) as Option_2 
        ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID;

감사!


가장 쉬운 방법은 여기에서 GROUP_CONCAT 그룹 함수를 사용하는 것입니다 ..

select
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  GROUP_CONCAT(Ordered_Options.Value) as `Options`
from
  ordered_item,
  ordered_options
where
  ordered_item.id=ordered_options.ordered_item_id
group by
  ordered_item.id

다음과 같이 출력됩니다.

Id              ItemName       Options

1               Pizza          Pepperoni,Extra Cheese

2               Stromboli      Extra Cheese

이렇게하면 쿼리를 수정하지 않고도 원하는만큼 많은 옵션을 사용할 수 있습니다.

아, 결과가 잘리는 경우 다음과 같이 GROUP_CONCAT의 크기 제한을 늘릴 수 있습니다.

SET SESSION group_concat_max_len = 8192;

도움을 주셔서 감사합니다. 누군가가 효과에 대해 언급한다면 해결책을 찾았다 고 생각합니다. 본질적으로 내가 한 일은. 구현에서 다소 정적 인 것을 알지만 필요한 작업을 수행합니다 (잘못된 구문 용서).

SELECT
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  Options1.Value
  Options2.Value
FROM ORDERED_ITEMS
LEFT JOIN (Ordered_Options as Options1)
    ON (Options1.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID 
        AND Options1.Option_Number = 43)
LEFT JOIN (Ordered_Options as Options2)
    ON (Options2.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID
        AND Options2.Option_Number = 44);

결과에 여러 열이 실제로 필요하고 옵션의 양이 제한되어 있다면 다음과 같이 할 수도 있습니다.

select
  ordered_item.id as `Id`,
  ordered_item.Item_Name as `ItemName`,
  if(ordered_options.id=1,Ordered_Options.Value,null) as `Option1`,
  if(ordered_options.id=2,Ordered_Options.Value,null) as `Option2`,
  if(ordered_options.id=43,Ordered_Options.Value,null) as `Option43`,
  if(ordered_options.id=44,Ordered_Options.Value,null) as `Option44`,
  GROUP_CONCAT(if(ordered_options.id not in (1,2,43,44),Ordered_Options.Value,null)) as `OtherOptions`
from
  ordered_item,
  ordered_options
where
  ordered_item.id=ordered_options.ordered_item_id
group by
  ordered_item.id

원하는 것은 피벗이라고하며 MySQL에서 직접 지원되지 않습니다.이 답변에서 옵션을 확인하십시오.

MySQL 엔티티 속성 값 스키마를 피벗하는 방법


최대 옵션 수가 제한 될 것이라는 것을 알고 있다면 다음을 시도해 볼 것입니다 (주문 당 최대 4 개 옵션의 예).

OI.ID, OI.Item_Name, OO1.Value, OO2.Value, OO3.Value, OO4.Value 선택

주문 항목 OI에서
    LEFT JOIN Ordered_Options OO1 ON OO1.Ordered_Item_ID = OI.ID
    LEFT JOIN Ordered_Options OO2 ON OO2.Ordered_Item_ID = OI.ID AND OO2.ID != OO1.ID
    LEFT JOIN Ordered_Options OO3 ON OO3.Ordered_Item_ID = OI.ID AND OO3.ID != OO1.ID AND OO3.ID != OO2.ID
    LEFT JOIN Ordered_Options OO4 ON OO4.Ordered_Item_ID = OI.ID AND OO4.ID != OO1.ID AND OO4.ID != OO2.ID AND OO4.ID != OO3.ID

GROUP BY OI.ID, OI.Item_Name

The group by condition gets rid of all of the duplicates that you would otherwise get. I've just implemented something similar on a site I'm working on where I knew I'd always have 1 or 2 matched in my child table, and I wanted to make sure I only had 1 row for each parent item.


Here is how you would construct your query for this type of requirement.

select ID,Item_Name,max(Flavor) as Flavor,max(Extra_Cheese) as Extra_Cheese
    from (select i.*,
                    case when o.Option_Number=43 then o.value else null end as Flavor,
                    case when o.Option_Number=44 then o.value else null end as Extra_Cheese
                from Ordered_Item i,Ordered_Options o) a
    group by ID,Item_Name;

You basically "case out" each column using case when, then select the max() for each of those columns using group by for each intended item.

참고URL : https://stackoverflow.com/questions/1067428/combine-multiple-child-rows-into-one-row-mysql

반응형