2009-07-01 39 views
52

Cảm ơn trước, tôi dường như không thể hiểu được!Kết hợp nhiều hàng con thành một hàng MYSQL

Tôi có hai bảng

Ordered_Item

ID | Item_Name 
1 | Pizza 
2 | Stromboli

Ordered_Options

Ordered_Item_ID | Option_Number | Value 
     1    43   Pepperoni 
     1    44   Extra Cheese 
     2    44   Extra Cheese

Những gì tôi đang tìm kiếm để đầu ra là một truy vấn mysql được cái gì đó để tác động này

Output

ID | Item_Name | Option_1 | Option_2 
1 Pizza  Pepperoni Extra Cheese 
2 Stromboli  NULL  Extra Cheese

Tôi đã cố gắng rất nhiều lựa chọn nhất kết thúc do lỗi cú pháp, tôi đã cố gắng group_concat nhưng thats không thực sự những gì tôi đang tìm kiếm. Tôi có một ví dụ thô dưới đây về những gì tôi nghĩ có thể là một sự khởi đầu. Tôi cần các tùy chọn để được theo thứ tự giống nhau mỗi lần. Và trong chương trình mà thông tin được thu thập thì không có cách nào để đảm bảo chắc chắn điều đó sẽ xảy ra. Có thể ghép chúng theo số tùy chọn hay không. Ngoài ra tôi biết rằng tôi sẽ không bao giờ có hơn 5 tùy chọn để giải pháp tĩnh sẽ hoạt động

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; 

Cảm ơn! Joe

Trả lời

90

Cách đơn giản nhất sẽ được tận dụng các nhóm GROUP_CONCAT chức năng ở đây ..

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 

nào sẽ ra:

Id    ItemName  Options 

1    Pizza   Pepperoni,Extra Cheese 

2    Stromboli  Extra Cheese 

Bằng cách đó bạn có thể có nhiều lựa chọn như bạn muốn mà không phải sửa đổi truy vấn của bạn.

Ah, nếu bạn thấy kết quả của bạn bị cắt, bạn có thể tăng giới hạn kích thước của GROUP_CONCAT như thế này:

SET SESSION group_concat_max_len = 8192; 
+3

anh ấy nói "Tôi đã thử group_concat nhưng đó không thực sự là những gì tôi đang tìm kiếm". –

+0

Xin chào, Cảm ơn bạn đã phản hồi nhanh nhưng tôi e rằng tôi không bao gồm một phần thông tin quan trọng. Tôi cần các tùy chọn để được theo thứ tự giống nhau mỗi lần. Và trong chương trình mà thông tin được thu thập thì không có cách nào để đảm bảo chắc chắn điều đó sẽ xảy ra. Có thể ghép chúng theo số tùy chọn hay không. Ngoài ra tôi biết rằng tôi sẽ không bao giờ có hơn 5 lựa chọn vì vậy một giải pháp tĩnh sẽ làm việc. –

+4

Để đặt hàng các mặt hàng trong nhóm, bạn có thể thực hiện việc này ví dụ: GROUP_CONCAT (Ordered_Options.Value ORDER BY Ordered_Options.value), –

8

tôi đánh giá cao sự giúp đỡ, tôi nghĩ rằng tôi đã tìm thấy một giải pháp nếu ai đó nhận xét về tính hiệu quả tôi sẽ đánh giá cao nó. Về cơ bản những gì tôi đã làm là.Tôi nhận ra nó là một chút tĩnh trong việc thực hiện của nó nhưng tôi làm những gì tôi cần nó để làm (tha thứ cú pháp không chính xác)

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); 
+4

Việc này sẽ khó duy trì. Sớm hay muộn khách hàng của bạn sẽ muốn có một lựa chọn thứ 3 hoặc thứ 4, và sau đó bạn cần phải viết lại tất cả mọi thứ. –

+0

Đã thêm một câu trả lời khác cho kết quả tương tự như truy vấn mà bạn đã đăng, nhưng nó linh hoạt hơn một chút. Bạn vẫn có thể có số lượng tùy chọn không giới hạn, trong khi vẫn nhận được nhiều cột cho các tùy chọn bánh pizza trong kết quả của bạn. –

1

Nếu bạn thực sự cần nhiều cột trong kết quả của bạn, và số lượng tùy chọn là có hạn, bạn có thể thậm chí làm điều này:

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 
1

Nếu bạn biết bạn sẽ có một số giới hạn các tùy chọn tối đa sau đó tôi sẽ cố gắng này (ví dụ cho tối đa là 4 lựa chọn mỗi đơn hàng):

Select OI.ID, OI.Item_Name, OO1.Value, OO2.Value, OO3.Value, OO4.Value 

FROM Ordered_Items 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

các g roup theo điều kiện được loại bỏ tất cả các bản sao mà bạn sẽ nhận được. Tôi đã thực hiện một cái gì đó tương tự trên một trang web tôi đang làm việc trên nơi tôi biết tôi luôn luôn có 1 hoặc 2 phù hợp trong bảng con tôi, và tôi muốn chắc chắn rằng tôi chỉ có 1 hàng cho mỗi mục cha mẹ.

0

dưới đây là cách bạn sẽ xây dựng truy vấn của mình cho loại yêu cầu này.

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; 

về cơ bản, bạn "loại bỏ" từng cột bằng "trường hợp khi". sau đó chọn "max()" cho mỗi cột trong số các cột đó bằng cách sử dụng "nhóm theo" cho từng mục được dự định.

Các vấn đề liên quan