Why does calling MAX on a subquery fail in SELECT? - mysql

Can anyone help me answer why my query returns a syntax error? I'm working on the Hackerrank problem linked here.
Here's the code I wrote:
SELECT MAX(SELECT e1.salary * e1.months FROM Employee as e1) as max_tot_earnings, COUNT(e.employee_id)
FROM Employee as e
WHERE e.salary * e.months = max_tot_earnings
I get the following syntax error:
ERROR 1064 (42000) 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 'SELECT e1.salary * e1.months FROM Employee
as e1) as max_tot_earnings, COUNT(e.e' at line 1
I know that the subquery doesn't have a syntax error. It runs just fine when run on its own. I was also able to work around the problem, so the purpose of this question is to try and figure out what's going on. I was able to solve the problem with the query shown below:
SELECT (SELECT e1.salary * e1.months as tot_earnings FROM Employee as e1 ORDER BY tot_earnings DESC LIMIT 1) as max_tot_earnings, COUNT(e.employee_id)
FROM Employee as e
GROUP BY e.salary, e.months
HAVING e.salary * e.months = max_tot_earnings
I found a few questions here that touch on using SELECT MAX(SELECT ...), but I didn't find answers for the two questions as phrased above. Questions one, two, and three.
In sum, I have two main questions:
Why does the SELECT MAX(SELECT ...) approach return a syntax error? I've used MAX(SELECT ...) statements in HAVING before, so I'm puzzled. Are aggregate functions with subqueries just not allowed in SELECT?
In my search online for an answer to #1, I have seen suggestions move the subquery in the FROM statement. Is this preferable to having the subquery in my SELECT statement (as in my eventual solution shown above)?

The correct syntax is:
SELECT (SELECT MAX(e1.salary * e1.months) FROM Employee as e1) as max_tot_earnings,
COUNT(e.employee_id)
FROM Employee as e
WHERE e.salary * e.months = max_tot_earnings;
Or more simply as:
SELECT (e.salary * e.months) as max_tot_earnings, COUNT(*)
FROM Employee
GROUP BY max_tot_earnings
ORDER BY max_tot_earnings DESC
LIMIT 1;
Your query doesn't work for the following reasons:
A subquery needs its own set of parentheses. So does a function call. So MAX( (SELECT . . . ) ) at least meets the parentheses requirements.
The MAX() function takes an argument that is either a column reference or a constant or an expression that evaluates to a scalar. Your function call does not do that.
MAX() doesn't allow subqueries at all, even scalar subqueries.

Related

Laravel 5.8, Tricky subquery with Count(*) in where clause

I need to write a little tricky subquery in where clause
So, I have a query like this
Select * FROM table1
JOIN table2 ...
LEFT JOIN table3 ...
WHERE (SELECT COUNT(*) FROM some_table where some_condition) = 0;
The SQL works fine, but how can I move it into the Laravel?
Yeah, I know that I should use DB::raw() but the problem is the subquery returns count. So, for example, the count is 5454. After that, I'm having something like this.
->where(5454, '=', 0)
and it gives me obvious error message: Unknown column 5454 ...
I've tried also to use AS count for the subquery but in that case, I'm having another obvious error message: Syntax error 0_0
So, any suggestions?
Try
whereRaw("(SELECT COUNT(*) FROM some_table where some_condition) = 0")
This will help you.

WorkbenchJ - Error: aggregates not allowed in GROUP BY clause

I found a few other threads with this error message on the site but the solutions there did not seem to work for me.
This is the query I am trying to run:
SELECT
o.name as Name,
o.vrank_tav__c as Vrank,
COUNT(c.enterprise_id) AS #_users_enterprise
FROM
(community_csv_james c JOIN
salesforce_data_opportunity o ON
c.enterprise_id = o.enterprise_id__c)
GROUP BY #_users_enterprise, Name, Vrank
ORDER BY #_users_enterprise DESC;
When I run it on SQL Workbench J, I get the following error:
SELECT
o.name as Name,
o.vrank_tav__c as Vrank,
COUNT(c.enterprise_id) AS #_users_enterprise
FROM
(community_csv_james c JOIN
salesforce_data...
ERROR: aggregates not allowed in GROUP BY clause
I've tried a few variations of this but I that promoted different error messages. How should I write this query?
Thanks!
You are not supposed to include the results from your aggregate function (your Count()) in your group by. The count is going to be associated with a distinct name/Vrank so you would only need to group on those. That's why it's giving you that specific error.
GROUP BY Name, Vrank
MySQL documentation for GROUP BY

Prestashop - List view filter

I insert an other column in the list view of my module inserting the values with getList function, I modified the sql to filter in the renderList function but I can't use the alias in where clause.
How can I fix it?
The error i got is the next:
Uncaught Unknown column 'product_supplier_name' in 'where clause'<br /><br />
SELECT SQL_CALC_FOUND_ROWS a.* , s.name AS product_supplier_name FROM ps_supplier_bill a LEFT JOIN ps_supplier s ON s.id_supplier = a.id_product_supplier WHERE 1 AND product_supplier_name LIKE '%fa%' ORDER BY product_supplier_name asc LIMIT 0,50
The proper query should be this:
SELECT SQL_CALC_FOUND_ROWS a.* , s.`name` AS product_supplier_name FROM `ps_supplier_bill` a LEFT JOIN `ps_supplier` s ON s.`id_supplier` = a.`id_product_supplier` WHERE 1 AND s.`name` LIKE '%fa%' ORDER BY s.`name` asc LIMIT 0,50
It's not possible use directly an alias in WHERE, because chronologically, WHERE happens before SELECT, which always is the last step in the execution chain. REFER
From MySQL doc:
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined.
MySQL doc

MySQL IF() Sub Select

I am having trouble with doing a SUB SELECT in an IF() condition.
I'm trying to get it to select select the MIN saved time if the type does not equal a certain value, excluding that value from the calculation.
Here is my current SQL query that works except for the IF():
SELECT
t.episode,
t.anime_id,
MAX(t.type) as type,
MIN(t.HD) as HD,
MAX(t.thumbnail) as thumbnail,
IF((MAX(t.type)!="raw"),(SELECT MIN(e.saved) FROM anime_episodes e WHERE e.type=MAX(t.type) AND t.episode=e.episode AND t.anime_id=e.anime_id GROUP BY e.anime_id, e.episode), (MIN(t.saved))) as time,
// UP HERE ^
MAX(t.filler) as filler,
m.anime_name,
m.furl,
m.video_thumb
FROM anime_episodes t
LEFT JOIN anime_list m ON
( t.anime_id=m.anime_id )
WHERE t.approved=1 AND t.locked=0 AND m.status=0 AND t.episode>=m.latest_ep
GROUP BY t.anime_id, t.episode
ORDER BY time DESC LIMIT 0,24
Is there something going on with my syntax? It looks fine to me but the error is:
SQL error: 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 'WHERE type!="raw")) as time, MAX(t.filler) as filler,m.anime_name, m.furl, m.vid' at line 1
EDIT: Correct answer, but I had to add some grouping as it was returning more than one result. Thank you!
You have forgot to add the from table statement
Try this::
SELECT
t.episode,
t.anime_id,
MAX(t.type) as type,
MIN(t.HD) as HD,
MAX(t.thumbnail) as thumbnail,
IF((type="raw"),(MIN(t.saved)), (SELECT MIN(saved) from anime_episodes WHERE type!="raw")) as time,
// UP HERE ^
MAX(t.filler) as filler,
m.anime_name,
m.furl,
m.video_thumb
FROM anime_episodes t
LEFT JOIN anime_list m ON
( t.anime_id=m.anime_id )
WHERE t.approved=1 AND t.locked=0 AND m.status=0 AND t.episode>=m.latest_ep
GROUP BY t.anime_id, t.episode
ORDER BY time DESC LIMIT 0,24

Zend_Db_Select - Joins and Count - Possible Zend Bug?

I'm having an issue getting a COUNT() from a SQL query using Zend_Db_Table_Select, and I think it may be a possible bug because the SQL it should be generating actually works. Here's the Zend Select Query: ($this is a Zend_Db_Table, renamed to table1 in this example)
$select = $this->select();
$select->setIntegrityCheck(false);
// Select Count
$select->from($this, array("COUNT(*) as 'COUNT'"))
->joinLeft('users', 'table1.userID = users.userID')
->joinLeft('table2', 'users.anotherKey = table2.anotherKey');
// Add Where clause after join
$select->where('users.anotherKey = ?', $anotherKeyValue);
This gives the error:
SQLSTATE[42000]: Syntax error or access violation: 1140
Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is
illegal if there is no GROUP BY clause`
However, this query...
SELECT COUNT(*) AS 'count' FROM table1
LEFT JOIN users ON table1.userID = users.userID
LEFT JOIN table2 ON users.anotherKey = table2.anotherKey
WHERE users.anotherKey = [anotherKeyValue]
...returns the expected results with no errors when run against the database. Any ideas whats going on, why the error, and how to get around it?
have you tried to see actual query, that zend_db produce?