Oracle says scalar subqueries are not valid expressions in the following places:
In WHEN conditions of CASE expressions
In GROUP BY and HAVING clauses
But why the following queries don't give any error.(Don't go to the purpose,I am just trying some random examples)
select case when (select id from employee where id=60)=60 then 1 end if from employee;
select id from employee group by id having (select id from employee where id=60)=60;
Let there be only one id with value 60
Related
Can you filter a SQL table based on an aggregated value, but still show column values that weren't in the aggregate statement?
My table has only 3 columns: "Composer_Tune", "_Year", and "_Rank".
I want to use SQL to find which "Composer_Tune" values are repeated in each annual list, as well as which ranks the duplicated items had.
Since I am grouping by "Composer_Tune" & "Year", I can't list "_Rank" with my current code.
The image shows the results of my original "find the duplicates" query vs what I want:
Current vs Desired Results
I tried applying the concepts in this Aggregate Subquery StackOverflow post but am still getting "_Rank is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" from this code:
WITH DUPE_DB AS (SELECT * FROM DB.dbo.[NAME] GROUP BY Composer_Tune, _Year HAVING COUNT(*)>1)
SELECT Composer_Tune, _Year, _Rank
FROM DUPE_DB
You need to explicitly declare the columns used in the Group By expression in the select columns.
You can use the following documentation if you are using transact sql for the proper use of Group By.
Simply join the aggregated resultset to original unit level table:
WITH DUPE_DB AS (
SELECT Composer_Tune, _Year
FROM DB.dbo.[NAME]
GROUP BY Composer_Tune, _Year
HAVING COUNT(*) > 1
)
SELECT n.Composer_Tune, n._Year, n._Rank
FROM DB.dbo.[NAME] n
INNER JOIN DUPE_DB
ON n.Compuser_Tune = DUPE_DB.Composer_Tune
AND n._Year = DUPE_DB._Year
ORDER n.Composer_Tune, n._Year
I am getting the error
ORA-01795 maximum number of expressions in a list is 1000
for the below query
select emp_id, emp_name, emp_code
from emp e
where emp_id in (001,002,005,006....18000);
I need to put 18000 records in the IN clause. How can I achieve this? How can I modify my given query?
You can (and almost surely should) put the "records" (the values) in a table. Then you can do a join as #jpw suggested in a Comment; an IN condition is treated by the query engine as a join anyway.
Or, if you want to use the IN syntax, you still need the values in a table, and rewrite the condition as
... where emp_id in ( select id from this_table )
where "this_table" is the name of this new table, and "id" is the column name. The 1000 expression limit applies to expressions that you hard-code in the IN list, it does not apply to the number of results returned by a subquery.
I'll explain my problem so it becomes clearer.
I have to select the hospital with the biggest amount of medics.
My table looks like this :
Medic_Hospital values (codhospital,codmedic)
I have tried :
SELECT MAX(codmedic) FROM Medic_Hospital
but that only returns the number 6
( which is one of the medic's id )
SELECT codhospital,count(codmedic) FROM Medic_Hospital
where max(codmedic) = count(codmedic)
group by codhospital
but this also failed as
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
SELECT codhospital,MAX(COUNT(codmedic)) from Medic_Hospital
but that failed as
"Cannot perform an aggregate function on an expression containing an
aggregate or a subquery."
I'm not very experienced in SQL and I can see that my logic is failing me here. Could someone point me in the right direction please?
You could use the top clause to return just the first row of an ordered query:
SELECT TOP 1 codhospital, COUNT(codmedic)
FROM Medic_Hospital
GROUP BY codhospital
ORDER BY 2 DESC
fiddle here
SELECT DISTINCT NAME
FROM employee MINUS
SELECT NAME FROM salary;
SELECT DISTINCT NAME
FROM employee
WHERE NAME NOT IN (SELECT NAME
FROM salary);
Was thinking the result should be the same but it isn't. Anyone explain why it's not?
MINUS is not a supported keyword in MS SQL Server. If you look at the execution plan it is parsing MINUS as a table alias for employee - it's the equivalent of:
SELECT DISTINCT [MINUS.]NAME
FROM employee [AS] MINUS
The entire query is then parsed as two separate queries:
SELECT DISTINCT [MINUS.]NAME
FROM employee [AS] MINUS
<-- break -->
SELECT NAME FROM salary
where the implied terms are in brackets ([])
SQL Fiddle does not seem to be showing the multiple result sets properly.
The equivalent keyword to Oralcle's MINUS in SQL Server is EXCEPT:
SELECT DISTINCT NAME
FROM employee EXCEPT
SELECT NAME FROM salary;
My sample sql query
SELECT EID,p,p1,p2,p3 FROM table 1 GROUP BY EID;
Giving error not part of aggregate function.I wanted to group by only EID not all other p,p1,p2,p3. How do i specify that in sql query.
In most dialects of SQL, you have to specify which column you want, if the column is not in the group by clause. For instance, maybe you want the minimum value:
SELECT EID, min(p), min(p1), min(p2), min(p3)
FROM table 1
GROUP BY EID;
Or, if you wanted all the values from a particular record, use first or last:
SELECT EID, first(p), first(p1), first(p2), first(p3)
FROM table 1
GROUP BY EID;