Subquery returning multiple columns - mysql

I am writing a select subquery that returns a COUNT. However, I need to use a HAVING clause in the subquery and as a result need to specify that column in my subquery SELECT. So the result is that I have 2 columns: COUNT and column_for_having_clause.
Is there any way that i can tell SQL to take just the first column. I get an error saying
"Operand should contain 1 column(s)". I figure this must be a common problem, does anyone know a way around it?
Also, is there a way you can execute a HAVING clause without specifying the column in your SELECT query?
Thanks!

You could do
SELECT blah FROM foo WHERE bar = (SELECT cnt FROM (SELECT cnt, column_for_having_clause FROM table .... HAVING ... LIMIT 1))
Quite ugly however.

Sure, you can specify virtually any expression you want in the HAVING clause. It doesn't have to be a column from the select-list.
SELECT ...
FROM foo
WHERE x = (SELECT COUNT(*) FROM bar
GROUP BY y HAVING y = MAX(y));
But you can also, if you're comparing the count to something in the outer query, compare tuples.
SELECT ...
FROM foo
WHERE (x, 1) = (SELECT COUNT(*), y = MAX(y) AS is_max FROM bar
GROUP BY y HAVING is_max = 1);

Related

Mysql: Is it possible to use a subquery inside a from clause in order to pick the table name from another table

I was wondering if there's any way to add a subquery with a switch case to the form clause of my select query in order to select a table based on a condition.
For example:
select a.*
from (select (case when (table2.column = 'something')
then (table2.tablename1)
else (table2.tablename2)) as tablename
from table2
where table2.column2 = 'blabla'
limit 1
) a
I tried to write that in many variation & so far non of them worked.
On the most successful tryouts (when I got no mysql errors) it returned the name of the table as the result itself (for example: the value that's in table2.tablename2). I understand why it did that (because I selected everything from a select results...) but how can I use the tablename from the results in order to set the table on the main query?
Hope that make sense...
Any idea?

MySQL how to group into subgroups of rows

I have this DB: (note id is unique)
I am trying to get this:
What would be an efficient SQL query to achieve this?
SELECT
DISTINCT
foo2.group_id AS group_id,
if(foo1.group_id = foo2.group_id, foo1.id, NULL) AS id,
if(foo1.group_id = foo2.group_id, foo1.some_attr, NULL) AS some_attr
FROM mytable AS foo1
JOIN
(SELECT DISTINCT group_id FROM mytable) as foo2
ORDER BY group_id, id
You seem to be mixing a result set with formatting of the result set. SQL result sets are tables of consistent rows. The closest you can come is to change the sequence of your column names in the SELECT statement. You'll have to add your own line breaks at time of presentation.

Is it possible to compare a COUNT() with a single result of a SELECT in HAVING clause?

I have a question on HAVING statement in SQL.
Is a query like this possible?
SELECT COUNT(T.IDtif) AS NumeroTifosi
FROM Tifosi T, Partita P
WHERE T.IDtif=P.Tifoso AND P.Partita=P.Idpar
HAVING COUNT(P.Idpar) = ( SELECT COUNT(Idpar) FROM Partita
WHERE Data BETWEEN “2002101” AND ”20021231”)
I don't understand if it is possible to compare an aggregation function, in a HAVING statement, with a subquery that returns a single value.
That's what the parentheses do. You can compare a single result of a SELECT by turning telling SQL "it's ok, this has one value".
It could be:
SELECT ColA = (SELECT ColB from TableB Where Id = 1)
FROM TableA
or
SELECT *
FROM TableA
WHERE ColA = (SELECT ColB from TableB Where Id = 1)
or even with HAVING as you describe.
Yes. This query if perfectly valid. Are you getting an error when you try to run it?
What you are doing is running a subquery once to return a count. Then for each group, you are checking if the number of rows in that group is equal to the number returned by the subquery.

Interpreting a MySQL nested SELECT statement

I am not a MySQL expert by any means, but after reading the documentation for the SELECT statement, I did not find an answer to my problem.
I have this statement:
SELECT COUNT(*)=x.c FROM someTable,
(SELECT COUNT(*) c
FROM someTable
WHERE firstId <= secondId) x;
And I'm trying to figure out what the x.c means in the context of the query? Specifically, what is with the x that seems to be hanging out there?
I interpret the nested SELECT as SELECT COUNT(*) as c, making an alias for the row count as c, is that what the x is as well? What would it be an alias for?
Thanks!
The x is a table alias - a name for the nested SELECT statement in parentheses.
COUNT(*)=x.c
Is a boolean condition that the total row count of someTable be equal to the row count of someTable where firstId <= secondId
x.c is the column name for the count returned by the subquery.
They name the subquery "x" and in the subquery they name the count(*) "c". So "x.c" means the count returned by the subquery.
The x is an alias to the subquery - you will note that there is an x just after the subquery, denoting the alias name for it.
x is an alias for the table (SELECT COUNT(*) c FROM someTable WHERE firstId <= secondId).
MySQL requires that table subqueries have a unique alias. You'll notice there's an x at the end of the subquery, which makes the sub queries results appear as coming from table x.
In this case, x.c in the outer query means to refer to field c (the count result) in the aliased table x, which is the subquery.
X is an alias for joined someTable and the select you joined someTable with. I guess so :D
I guessed wrong, guys over me are right :P

MySQL reference result from subquery

This is what i am doing
update t1 set x=a,y=b where a and b are obtained from (select query here)
I know the select query
The select query returns multiple results which are the same
When I use group by or distinct query execution slows down considerably
a and b are forward references so mysql reports an error
I want to set a equal to the value obtained in the first row and b equal to the value obtained in the first row for the respective columns, to avoid group by. I don't know how to refer to the first result from the select query.
How can i achieve all this?
LIMIT specifies the number of rows to return from the beginning of the result set:
SELECT * FROM t2 LIMIT 1; # Retrieve 1st row
LIMIT in your case is applied in the subquery in your from clause.
These linsk can help you out with update that uses a subquery:
Update with Subquery
Subqueries in MySQL, Part 1
you might be looking for something like...
update T1, (select Sub1.a, Sub1.b from YourSubQueryTable Sub1 where ... ) SubResult
set T1.a = SubResult.a,
T1.b = SubResult.b
where
Some T1.Criteria To be applied