简体   繁体   中英

Data ends up in wrong columns using SELECT and GROUP BY on result of LEFT-RIGHT-JOIN-UNION and LEFT JOIN

I am an SQL newbie, sorry if the answer is obvious. Note that I have researched and tried to solve this for some 2h now. Please read carefully before considering this question redundant.

I would like to join three tables , one of which needs to be a full join , and then SELECT and GROUP BY on the result, such as here:

SELECT country, COUNT(DISTINCT customerNumber), SUM(priceEach*quantityOrdered) 
FROM orders 
LEFT JOIN orderdetails USING (orderNumber) 
FULL JOIN customers USING (customerNumber)
GROUP BY country;

Full joins are done with the UNION of a left and right join. Using SELECT and GROUP BY to calculate fields based on LEFT-RIGHT-JOIN-UNION and LEFT JOIN caused data to end up in the wrong columns in the final ouput . This did not work:

SELECT country, COUNT(DISTINCT customerNumber), SUM(priceEach*quantityOrdered) 
FROM (SELECT * FROM orders LEFT JOIN customers USING(customerNumber)
      UNION
      SELECT * FROM orders RIGHT JOIN customers USING(customerNumber)) as ocFull
LEFT JOIN orderdetails USING (orderNumber) 
GROUP BY country;

I cannot figure out my error. What am I doing wrong? Alternatively, how is this usually done? Please help!

There were two solutions to this problem: making all fields in all SELECT statements explicit (naming them instead of using * ) or removing the GROUP BY statement. The first is the exact solution to my problem.

Make fields explicit:

SELECT country, COUNT(DISTINCT customerNumber) AS N_customers, SUM(priceEach*quantityOrdered) AS total_sales 
    FROM (SELECT country, customerNumber, orderNumber FROM orders LEFT JOIN customers USING(customerNumber)
          UNION
          SELECT country, customerNumber, orderNumber FROM orders RIGHT JOIN customers USING(customerNumber)) as ocFull
    LEFT JOIN orderdetails ON orderdetails.orderNumber = ocFull.orderNumber
    GROUP BY country;

Remove GROUP BY: Curiously, removing the GROUP BY statement fixed the issue. It seems that this affects the field order prior to completing all the joins in some way, leading to some data appearing in the wrong columns.

SELECT *  FROM 
(SELECT * FROM orders LEFT JOIN customers USING(customerNumber)
      UNION
      SELECT * FROM orders RIGHT JOIN customers USING(customerNumber)) as ocFull
LEFT JOIN orderdetails USING (orderNumber);

Please note that if GROUP BY is removed, it no longer makes sense to COUNT(), SUM() etc., since this was intend to take place across countries, so the SELECT statement was reduced to *.

If you have a similar problem or would like to reproduce the issue, the classicmodels database in question was taken from: mysqltutorial

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