简体   繁体   中英

MySQL concat columns and rows from multiple tables

I'm trying to concatenate data from three related tables according to:

orders    orderrow             orderrow_op
+----+    +----+----------+    +----+-------------+
| id |    | id | id_order |    | id | id_orderrow |
+----+    +----+----------+    +----+-------------+
| 1  |    | 1  | 1        |    | 1  | 1           |
| 2  |    | 2  | 1        |    | 2  | 1           |
| 3  |    | 3  | 2        |    | 3  | 2           |
+----+    | 4  | 3        |    | 4  | 3           |
          +----+----------+    | 5  | 3           |
                               | 6  | 3           |
                               +----+-------------+

The result i'm looking for is something like:

orderops (Desired Result)

+----------+-----------------+
| id_order | id_row:id_ops   |
+----------+-----------------+
|    1     | 1:(1,2); 2:(3); |
|    2     | 3:(4,5,6)       |
|    3     | 4:NULL          |
+----------+-----------------+

Ie i want the operations and rows all be displayed on one row related to the order. So far i've tried things like:

SELECT
    db.orders.id AS orderid,
    db.orderrow.id AS rowids,
    GROUP_CONCAT(DISTINCT db.orderrow.id) AS a,
    GROUP_CONCAT(db.orderrow.id, ':', db.orderrow_op.id) AS b
FROM
    db.orders
    LEFT JOIN db.orderrow ON db.orders.id = db.orderrow.id_order
    LEFT JOIN db.orderrow_op ON db.orderrow.id = db.orderrow_op.id_orderrow
GROUP BY orderid

Where in column 'a' i get the row ids and in column 'b' i get the operation_ids with corresponding row_id prepended. I'd like to combine the two into a single column such that related values in 'b' will start of with id from 'a' and only show once.

I'm fairly new to MySQL so i don't know if this is even possible or if i'ts a good idea at all? The aim is to structure the data into JSON for delivery via REST application so perhaps it's better to deliver the rows directly to the webserver and handle json parsing over there? I just figured that this approach might be faster.

This is not the nicest query but it's working for your example table setup.

SELECT 
    o.id AS id_order,
    group_concat(sub.ops
        SEPARATOR ' ') AS id_row_id_ops
FROM
    (SELECT 
        orderrow.id_order,
            IF(isnull(l3.ops), concat(orderrow.id, ':', 'NULL'), concat(orderrow.id, ':', l3.ops)) as ops
    FROM
        orderrow
    LEFT JOIN (SELECT 
        orderrow_op.id_orderrow,
            concat('(', group_concat(orderrow_op.id), '); ') as ops
    FROM
        orderrow_op
    GROUP BY orderrow_op.id_orderrow) l3 ON l3.id_orderrow = orderrow.id) sub
        LEFT JOIN
    orders o ON o.id = sub.id_order
GROUP BY o.id;

One of the things to mind is the LEFT JOIN and that you need to cast a "null" value to a "null" text (otherwise your element 4 will vanish).

The output:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM