我有两个无法解决的问题。
在这种特定情况下,我需要在单个MySQL查询中将多个表与自定义输出结合并合并。
去除非必要列并包含假数据的表是:
transactions
+----+-------------+------------+--------+
| id | vendor_id | payment_id | amount |
+----+-------------+------------+--------+
| 1 | 12 | 45 | 25 |
| 2 | 13 | 46 | 50 |
| 3 | 14 | 47 | 50 |
| 4 | 15 | 48 | 50 |
+----+-------------+------------+--------+
vendors
+-----+-------------+
| id | vendor_code |
+-----+-------------+
| 12 | abc123 |
| 13 | efg321 |
| 14 | hjk456 |
| 15 | fed789 |
+-----+-------------+
payments
+-----+-------+--------+
| id | order | amount |
+-----+-------+--------+
| 45 | 0032 | 25 |
| 46 | 0063 | 50 |
| 47 | 0073 | 50 |
| 48 | 0087 | 50 |
+-----+-------+--------+
refunds
+----+----------------+--------+
| id | transaction_id | amount |
+----+----------------+--------+
| 65 | 2 | 10 |
+----+----------------+--------+
properties
+-----+----------+
| id | group_id |
+-----+----------+
| 100 | 222 |
| 200 | 333 |
+-----+----------+
vendor_properties
+----+-------------+------------+
| id | property_id | vendor_id |
+----+-------------+------------+
| 1 | 100 | 12 |
| 2 | 200 | 12 |
| 3 | 100 | 13 |
| 4 | 200 | 14 |
+----+-------------+------------+
groups
+-----+---------+
| id | name |
+-----+---------+
| 222 | groupA |
| 333 | groupB |
+-----+---------+
存在以下关系:
transactions.payment_id -> payments.id
transactions.vendor_id -> vendors.id
payments.vendor_id -> vendors.id
refunds.transaction_id -> transactions.id
properties.property_group_id -> groups.id
vendor_properties.property_id -> properties.id
vendor_properties.vendor_id -> vendors.id
我当前的SQL查询是:
SELECT
`transactions`.`id` AS DB_transID,
`transactions`.`vendor_id` AS DB_vendID,
`vendors`.`vendor_code` AS "VendorCode",
`payments`.`order` AS "Order",
`transactions`.`amount` AS "Amount"
`refunds`.`amount` AS "Refunded",
`groups`.`name` AS "Group"
FROM
`transactions`
LEFT JOIN
`payments` ON `payments`.`id` = `transactions`.`payment_id`
LEFT JOIN
`vendors` ON `vendors`.`id` = `transactions`.`vendor_id`
LEFT JOIN
`refunds` ON `refunds`.`transaction_id` = `transactions`.`id`
LEFT JOIN
`groups` ON `groups`.`id` IN
(
SELECT `group_id` FROM `properties` WHERE `id` IN
(
SELECT `property_id` FROM `vendor_properties`
WHERE `vendor_id` = @refID
)
);
输出为:
+------------+-----------+------------+-------+--------+----------+--------+
| DB_transID | DB_vendID | VendorCode | Order | Amount | Refunded | Group |
+------------+-----------+------------+-------+--------+----------+--------+
| 1 | 12 | abc123 | 0032 | 25 | NULL | groupA |
| 1 | 12 | abc123 | 0032 | 25 | NULL | groupB |
| 2 | 13 | efg321 | 0063 | 50 | 10 | groupA |
| 3 | 14 | hjk456 | 0073 | 50 | NULL | groupB |
| 4 | 15 | fed789 | 0087 | 50 | NULL | NULL |
+------------+-----------+------------+-------+--------+----------+--------+
我想做的是:
因此所需的输出将是:
+------------+-----------+------------+-------+--------+----------+-----+----------------+
| DB_transID | DB_vendID | VendorCode | Order | Amount | Refunded | Net | Group |
+------------+-----------+------------+-------+--------+----------+-----+----------------+
| 1 | 12 | abc123 | 0032 | 25 | 0 | 25 | groupA, groupB |
| 2 | 13 | efg321 | 0063 | 50 | 10 | 40 | groupA |
| 3 | 14 | hjk456 | 0073 | 50 | 0 | 50 | groupB |
| 4 | 15 | fed789 | 0087 | 50 | 0 | 50 | None |
+------------+-----------+------------+-------+--------+----------+-----+----------------+
在现实生活中,大多数表中都有数千行。作为一个额外的问题,告诉我为什么即使有时数据应该有一个值,有时我仍会为Group获得NULL?
欢迎对该查询进行任何其他改进!
答案 0 :(得分:1)
这是我实现您目标的第一种方法,如果发现任何改进,我会进行更新:
SELECT
t.id AS DB_transID,
t.vendor_id AS DB_vendID,
t.amount AS Amount,
v.vendor_code AS VendorCode,
p.order AS "Order",
IFNULL(r.amount, 0) AS Refunded,
IFNULL(t.amount, 0) - IFNULL(r.amount, 0) AS Net,
IFNULL((
SELECT GROUP_CONCAT(DISTINCT g.name SEPARATOR ', ')
FROM vendor_properties vp
LEFT JOIN properties pr ON pr.id = vp.property_id
LEFT JOIN groups g ON g.id = pr.group_id
WHERE vp.vendor_id = t.vendor_id
GROUP BY vp.vendor_id
), "None") AS "Groups"
FROM
transactions t
LEFT JOIN
payments p ON p.id = t.payment_id
LEFT JOIN
vendors v ON v.id = t.vendor_id
LEFT JOIN
refunds r ON r.transaction_id = t.id;
对此上一个查询进行了改进,如果您的某些外键不允许使用NULL值,则可以使用LEFT JOIN
完成相关表之间的INNER JOIN
:>
SELECT
t.id AS DB_transID,
ANY_VALUE(t.vendor_id) AS DB_vendID,
ANY_VALUE(t.amount) AS Amount,
ANY_VALUE(v.vendor_code) AS VendorCode,
ANY_VALUE(p.order) AS "Order",
IFNULL(ANY_VALUE(r.amount), 0) AS Refunded,
IFNULL(ANY_VALUE(t.amount), 0) - IFNULL(ANY_VALUE(r.amount), 0) AS Net,
IFNULL(GROUP_CONCAT(DISTINCT g.name SEPARATOR ', '), "None") AS "Group"
FROM
transactions t
LEFT JOIN
payments p ON p.id = t.payment_id
LEFT JOIN
vendors v ON v.id = t.vendor_id
LEFT JOIN
refunds r ON r.transaction_id = t.id
LEFT JOIN
vendor_properties vp ON vp.vendor_id = t.vendor_id
LEFT JOIN
properties pr ON pr.id = vp.property_id
LEFT JOIN
groups g ON g.id = pr.group_id
GROUP BY
t.id
希望这对您有所帮助,您可以在此处使用工作示例: