If you like DNray Forum, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...

 

MySQL UNION and ORDER BY problem

Started by bachynskijosh, Sep 27, 2022, 01:29 AM

Previous topic - Next topic

bachynskijoshTopic starter

Hello, I am currently working on a beginner's website and have run into an issue with the following SQL code:

SELECT s.name, g.grade, s.marks
FROM Students s
INNER JOIN Grades g ON (min_mark <= s.marks) AND (s.marks <= max_mark)
WHERE g.grade > 9
/*ORDER BY g.grade DESC, s.name*/
UNION
SELECT REPLACE(s.name, '%', NULL), g.grade, s.marks
FROM Students s
INNER JOIN Grades g ON (min_mark <= s.marks) AND (s.marks <= max_mark)
WHERE g.grade <= 9
/*ORDER BY g.grade DESC, s.marks*/

The specific issue is that the rows with a value of grade > 9 need to be sorted in a specific way, while the remaining rows should be sorted differently. The problem is that while each part of the code works correctly on its own, using UNION to connect them results in an error:

ERROR 1065 (43000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION SELECT REPLACE(s.name, '%', NULL), g.grade, s.marks FROM Students s INNER' at line 6

Commenting out the ORDER BY lines allows the code to function without errors, but it fails to achieve the desired result. I would greatly appreciate any suggestions on how to proceed, as the topic of the problem relates to JOIN which may suggest that my approach to the solution is incorrect.
  •  

GrahamJohn

It seems that using UNION in this SQL code is unnecessary, and the REPLACE function being used to change all occurrences of '%' to NULL is odd as well. Additionally, there may not be a need to display names for grade values <= 9 at all. In terms of sorting, the following code can be used:

ORDER BY 2, CASE WHEN grade > 9 THEN name ELSE NULL END, 3
This will sort the data by the second column (grade), followed by the name column (if grade > 9), and then by the third column (marks).
  •  

Griereinifivy

The issue with your SQL code is that the ORDER BY clause cannot be used directly after UNION. To solve this problem, you can wrap your original query into a subquery and then apply the ORDER BY clause to the result of the UNION operation. Here's an example of how you can rewrite your code:

SELECT name, grade, marks FROM (
  SELECT s.name, g.grade, s.marks
  FROM Students s
  INNER JOIN Grades g ON (min_mark <= s.marks) AND (s.marks <= max_mark)
  WHERE g.grade > 9

  UNION

  SELECT REPLACE(s.name, '%', NULL), g.grade, s.marks
  FROM Students s
  INNER JOIN Grades g ON (min_mark <= s.marks) AND (s.marks <= max_mark)
  WHERE g.grade <= 9
) AS subquery
ORDER BY grade DESC, name;

Here's an explanation of the updated SQL code:

1. The original query is wrapped in a subquery by encasing it within parentheses. This allows us to treat the result of the UNION operation as a temporary table.

2. The subquery is given an alias "subquery" using the AS keyword. This alias can be used to refer to the result set of the subquery in the outer SELECT statement.

3. The ORDER BY clause is applied to the result set of the subquery in the outer SELECT statement. In this case, the result set will be sorted in descending order based on the "grade" column and then in ascending order based on the "name" column.

By using this approach, you can achieve the desired sorting for the rows with grade > 9 and the remaining rows separately.
  •  


If you like DNray forum, you can support it by - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 and more...