NOT IN vs MINUS not yielding same result - sql

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;

Related

MIN() Function with String in SQL

I have Name in employee table. I want to extract min length name. if data base contain two name with min. length both should be pick. or second question pick one name only based on alphabetically.
When I am doing this like
Query:
Select MIN(Name) From Employee;
Result:-Bharti
Why It's Happening?
Name|Length
Meera|5
Sameer|6
Bharti|6
Mahak|5
Bharti|6
Meera|5
MIN() gives the smallest string aphabetically, which is not the shortest string.
To get rows that have the shortest string, you can sort by length and keep the first rows only.
In SQL Server:
select top(1) with ties *
from mytable
order by len(name)
In databases the support the fetch row-limiting clause:
select *
from mytable
order by len(name)
fetch first row with ties
If none of these options is available:
select *
from mytable t
where len(name) = (select min(len(name)) from mytable)
The function that gets the length of a string varies across databases.
`You appear to be asking: Why does the following query return one row?
Select MIN(Name)
From Employee;
The MIN() in the SELECT makes this an aggregation query. It has no GROUP BY. By the definition of SQL, all rows in the table are treated as a single group in this case, and aggregation queries with no GROUP BY always return one row.
If you want all rows with the minimum length, then the length needs to appear somewhere, such as:
select e.name
from employee e
where len(e.name) = (select min(len(e2.name)) from employee);
If you want the first name alphabetically among the shortest names, there are multiple approaches, but a simple one is:
select e.name
from employee e
order by len(e.name), name
fetch first 1 row only;

SQL query - count with subquery

I want to get the count of all the columns that are retrieved in the query.I have used the below code:
select count (*)
from (
select distinct ID,salary,name,location
from test
) ;
I am getting an error message:
Incorrect error at ; expecting AS,ID or quoted_ID
When I add as below:
select count (*)
from (
select distinct ID,salary,name,location
from test
) as count;
The query works now but the column name is not renamed to the alias given. What is the logic behind this?
In Sql you have to give alias to subquery. So that's the reason the second query works and first one fails
i don't know what you are trying to achieve but to correct this would be
select count (*) from (select distinct ID,salary,name,location from test ) as myTAble;
subquery will act as your table to query from therefore it needs a
name or alias
You are giving alias to the table and not column. The following query would work.
select count (*) As count
from (
select distinct ID,salary,name,location
from test
) as tbl;

Why Scalar Subquery Expressions in the following queries did not violate rules?

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

SQL Query to select one field order by other field

I want to select a field in select statement and order by with another field but sql server doesn't allows this as it says order by item must appear in the select statement if select distinct is specified.
This is what I tried :
select DISTINCT format_type
from Labels_Add_Label
where external_group_id= 2826
order by group_sequence
What changes are required to do in this query?
Please provide the changed query
You can rewrite your query this way (equivalent to distinct):
SELECT format_type
FROM Labels_Add_Label
WHERE external_group_id= 2826
GROUP BY format_type;
and you can't use ORDER BY group_sequence here. There may be more than one row with same format_type but different group_sequence. SQL server doesn't know which one should be used for the ordering.
You can however use aggregate functions with a GROUP BY query:
SELECT format_type
FROM Labels_Add_Label
WHERE external_group_id= 2826
GROUP BY format_type;
ORDER BY MIN(group_sequence) ; -- or MAX(group_sequence)
I just took this question to test my knowledge and have come with the following solution (using CTE in MS SQL Server), please correct me if I'm wrong - Using the NORTHWIND Database (Employees Table) on MS SQL Server, I have written this query - This could be one other option that could be used, if there be a need to!
WITH CTE_Employees(FirstName, LastName, BirthDate)
AS
(
SELECT FirstName, LastName, BirthDate
FROM Employees
WHERE Region IS NOT NULL
)
SELECT FirstName FROM CTE_Employees ORDER BY BirthDate DESC
As mentioned above, there can be a same Employee FirstName but with a different LastName, hence SQL Server imposes a condition where we can't use DISTINCT in conjunction with ORDER BY...
Hope this helps!

How to SELECT columns without including them in GROUP BY access sql

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;