MySQL 中的 UNION 查询问题
UNION query issue in MySQL
看看我的 UNION
查询:
SELECT customer_id
, name as cname
, CASE
WHEN address <> ''
THEN CONCAT(address, ', ', city)
ELSE city
END as address
, null as total_sale
, null as total_paid
, null as total_due
FROM customer c
UNION
SELECT customer_id
, null as cname
, null as address
, sum(amount_due_tot) as total_sale
, sum(amount_paid_tot) as total_paid
, sum(amount_due_balance_tot) as total_due
FROM (
SELECT bad.basket_id as baskets
, bad.customer_id as customer_id
, bad.amount_due as amount_due_tot
, sum(COALESCE(p.amount_paid, 0)) as amount_paid_tot
, bad.amount_due - SUM(COALESCE(p.amount_paid, 0)) as amount_due_balance_tot
, sale_status_id
FROM basket_amount_due bad
LEFT JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
LEFT JOIN customer c ON b.customer_id = c.customer_id
WHERE b.sale_status_id = 4
GROUP BY basket_id, sale_status_id
) d
GROUP BY customer_id;
它returns结果如下所示:
+-------------+--------------------+-----------------+------------+------------+-----------+
| customer_id | cname | address | total_sale | total_paid | total_due |
+-------------+--------------------+-----------------+------------+------------+-----------+
| 1 | Customer Name 01 | NULL | NULL | NULL | NULL |
| 2 | Customer Name 02 | Address 02 | NULL | NULL | NULL |
| 3 | Customer Name 03 | Address 03 | NULL | NULL | NULL |
| 4 | Customer Name 04 | Address 04 | NULL | NULL | NULL |
| 5 | Customer Name 05 | Address 05 | NULL | NULL | NULL |
| 6 | Customer Name 06 | | NULL | NULL | NULL |
| 7 | Customer Name 07 | | NULL | NULL | NULL |
| 1 | NULL | NULL | 927.08 | 927.08 | 0.00 |
| 3 | NULL | NULL | 2576.80 | 2376.80 | 200.00 |
| 4 | NULL | NULL | 12118.00 | 4210.25 | 7907.75 |
| 6 | NULL | NULL | 870.00 | 270.00 | 600.00 |
+-------------+--------------------+-----------------+------------+------------+-----------+
但是从这个 UNION
查询我希望得到这个结果:
+-------------+--------------------+-----------------+------------+------------+-----------+
| customer_id | cname | address | total_sale | total_paid | total_due |
+-------------+--------------------+-----------------+------------+------------+-----------+
| 1 | Customer Name 01 | NULL | 927.08 | 927.08 | 0.00 |
| 2 | Customer Name 02 | Address 02 | NULL | NULL | NULL |
| 3 | Customer Name 03 | Address 03 | 2576.80 | 2376.80 | 200.00 |
| 4 | Customer Name 04 | Address 04 | 12118.00 | 4210.25 | 7907.75 |
| 5 | Customer Name 05 | Address 05 | 870.00 | 270.00 | 600.00 |
| 6 | Customer Name 06 | | NULL | NULL | NULL |
| 7 | Customer Name 07 | | NULL | NULL | NULL |
+-------------+--------------------+-----------------+------------+------------+-----------+
谁能告诉我我在这个查询中做错了什么?
您需要使用 join 而不是 union。
SELECT c.customer_id
, c.name as cname
, CASE
WHEN address <> ''
THEN CONCAT(c,address, ', ', c.city)
ELSE city
END as address
, sum(d.amount_due_tot) as total_sale
, sum(d.amount_paid_tot) as total_paid
, sum(d.amount_due_balance_tot) as total_due
FROM customer c
Left join
(
SELECT bad.basket_id as baskets
, bad.customer_id as customer_id
, bad.amount_due as amount_due_tot
, sum(COALESCE(p.amount_paid, 0)) as amount_paid_tot
, bad.amount_due - SUM(COALESCE(p.amount_paid, 0)) as amount_due_balance_tot
, sale_status_id
FROM basket_amount_due bad
LEFT JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
LEFT JOIN customer c ON b.customer_id = c.customer_id
WHERE b.sale_status_id = 4
GROUP BY basket_id, sale_status_id
) d
on c.customer_id = d.customer_id
GROUP BY c.customer_id;
您查询的第二部分 select 是所有具有到期金额的购物篮以及客户。您希望每个客户一个结果行。那么为什么要按购物篮和销售状态分组呢?为什么要取消地址?这似乎没有多大意义。我只希望:
SELECT c.customer_id
, c.name AS cname
, CONCAT_WS(', ', NULLIF(c.address, ''), c.city) AS address
, SUM(p.amount_due) AS total_sale
, COALESCE(SUM(p.amount_paid), 0) AS total_paid
, SUM(p.amount_due) - COALESCE(SUM(p.amount_paid), 0) AS total_due
FROM basket_amount_due bad
JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
JOIN customer c ON c.customer_id = bad.customer_id
WHERE b.sale_status_id = 4
GROUP BY c.customer_id
ORDER BY c.customer_id;
这仅显示在 basket_amount_due
table 中有条目的客户。如果您想要所有客户,则来自客户和外部的 select 加入其他 tables。
此查询还假定每个篮子 basket_amount_due
中最多有一行。你的也是。如果不是这种情况,则不要将其行与 basket_payment
行连接起来,而是在连接前进行聚合。否则你会得到不正确的结果。
看看我的 UNION
查询:
SELECT customer_id
, name as cname
, CASE
WHEN address <> ''
THEN CONCAT(address, ', ', city)
ELSE city
END as address
, null as total_sale
, null as total_paid
, null as total_due
FROM customer c
UNION
SELECT customer_id
, null as cname
, null as address
, sum(amount_due_tot) as total_sale
, sum(amount_paid_tot) as total_paid
, sum(amount_due_balance_tot) as total_due
FROM (
SELECT bad.basket_id as baskets
, bad.customer_id as customer_id
, bad.amount_due as amount_due_tot
, sum(COALESCE(p.amount_paid, 0)) as amount_paid_tot
, bad.amount_due - SUM(COALESCE(p.amount_paid, 0)) as amount_due_balance_tot
, sale_status_id
FROM basket_amount_due bad
LEFT JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
LEFT JOIN customer c ON b.customer_id = c.customer_id
WHERE b.sale_status_id = 4
GROUP BY basket_id, sale_status_id
) d
GROUP BY customer_id;
它returns结果如下所示:
+-------------+--------------------+-----------------+------------+------------+-----------+
| customer_id | cname | address | total_sale | total_paid | total_due |
+-------------+--------------------+-----------------+------------+------------+-----------+
| 1 | Customer Name 01 | NULL | NULL | NULL | NULL |
| 2 | Customer Name 02 | Address 02 | NULL | NULL | NULL |
| 3 | Customer Name 03 | Address 03 | NULL | NULL | NULL |
| 4 | Customer Name 04 | Address 04 | NULL | NULL | NULL |
| 5 | Customer Name 05 | Address 05 | NULL | NULL | NULL |
| 6 | Customer Name 06 | | NULL | NULL | NULL |
| 7 | Customer Name 07 | | NULL | NULL | NULL |
| 1 | NULL | NULL | 927.08 | 927.08 | 0.00 |
| 3 | NULL | NULL | 2576.80 | 2376.80 | 200.00 |
| 4 | NULL | NULL | 12118.00 | 4210.25 | 7907.75 |
| 6 | NULL | NULL | 870.00 | 270.00 | 600.00 |
+-------------+--------------------+-----------------+------------+------------+-----------+
但是从这个 UNION
查询我希望得到这个结果:
+-------------+--------------------+-----------------+------------+------------+-----------+
| customer_id | cname | address | total_sale | total_paid | total_due |
+-------------+--------------------+-----------------+------------+------------+-----------+
| 1 | Customer Name 01 | NULL | 927.08 | 927.08 | 0.00 |
| 2 | Customer Name 02 | Address 02 | NULL | NULL | NULL |
| 3 | Customer Name 03 | Address 03 | 2576.80 | 2376.80 | 200.00 |
| 4 | Customer Name 04 | Address 04 | 12118.00 | 4210.25 | 7907.75 |
| 5 | Customer Name 05 | Address 05 | 870.00 | 270.00 | 600.00 |
| 6 | Customer Name 06 | | NULL | NULL | NULL |
| 7 | Customer Name 07 | | NULL | NULL | NULL |
+-------------+--------------------+-----------------+------------+------------+-----------+
谁能告诉我我在这个查询中做错了什么?
您需要使用 join 而不是 union。
SELECT c.customer_id
, c.name as cname
, CASE
WHEN address <> ''
THEN CONCAT(c,address, ', ', c.city)
ELSE city
END as address
, sum(d.amount_due_tot) as total_sale
, sum(d.amount_paid_tot) as total_paid
, sum(d.amount_due_balance_tot) as total_due
FROM customer c
Left join
(
SELECT bad.basket_id as baskets
, bad.customer_id as customer_id
, bad.amount_due as amount_due_tot
, sum(COALESCE(p.amount_paid, 0)) as amount_paid_tot
, bad.amount_due - SUM(COALESCE(p.amount_paid, 0)) as amount_due_balance_tot
, sale_status_id
FROM basket_amount_due bad
LEFT JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
LEFT JOIN customer c ON b.customer_id = c.customer_id
WHERE b.sale_status_id = 4
GROUP BY basket_id, sale_status_id
) d
on c.customer_id = d.customer_id
GROUP BY c.customer_id;
您查询的第二部分 select 是所有具有到期金额的购物篮以及客户。您希望每个客户一个结果行。那么为什么要按购物篮和销售状态分组呢?为什么要取消地址?这似乎没有多大意义。我只希望:
SELECT c.customer_id
, c.name AS cname
, CONCAT_WS(', ', NULLIF(c.address, ''), c.city) AS address
, SUM(p.amount_due) AS total_sale
, COALESCE(SUM(p.amount_paid), 0) AS total_paid
, SUM(p.amount_due) - COALESCE(SUM(p.amount_paid), 0) AS total_due
FROM basket_amount_due bad
JOIN basket b USING (basket_id)
LEFT JOIN basket_payment p USING (basket_id)
JOIN customer c ON c.customer_id = bad.customer_id
WHERE b.sale_status_id = 4
GROUP BY c.customer_id
ORDER BY c.customer_id;
这仅显示在 basket_amount_due
table 中有条目的客户。如果您想要所有客户,则来自客户和外部的 select 加入其他 tables。
此查询还假定每个篮子 basket_amount_due
中最多有一行。你的也是。如果不是这种情况,则不要将其行与 basket_payment
行连接起来,而是在连接前进行聚合。否则你会得到不正确的结果。