SQL Select-IN query - sql

I have a numeric column named id in my table.
I want to select the queries which has id in 1,2,3 and the one which has 'null' in them.
I dont want to use the query like:
SELECT * FROM MYTABLE WHERE ID IN (1,2,3) OR ID IS NULL
Can I use something like :
SELECT * FROM MYTABLE WHERE ID IN (1,2,3,null)
Is this possible? The above query returns me the same result as for
SELECT * FROM MYTABLE WHERE ID IN (1,2,3)

Short answer? No. You must use the IS NULL predicate. NULL != NULL (two NULL values are not necessarily equal), so any type of equals NULL, in (..., NULL) is not going to work.

If you using oracle, this may be solution.
SELECT * FROM MYTABLE WHERE NVL(ID,-1) IN (1,2,3,-1)

You must use:
SELECT * FROM MYTABLE WHERE ID IN (1,2,3) OR ID IS NULL
NULL always requires the special handling of IS NULL.

in sql server
SELECT * FROM MYTABLE WHERE isnull(ID,0) IN (1,2,3,0)

Related

Hive Query with a large WHERE Condition

I am writing a HIVE query to pull about 2,000 unique keys from a table.
I keep getting this error - java.lang.StackOverflowError
My query is basic but looks like this:
SELECT * FROM table WHERE (Id = 1 or Id = 2 or Id = 3 Id = 4)
my WHERE clause goes all the way up to 2000 unique id's and I receive the error above. Does anyone know of a more efficient way to do this or get this query to work?
Thanks!
You may use the SPLIT and EXPLODE to convert the comma separated string to rows and then use IN or EXISTS.
using IN
SELECT * FROM yourtable t WHERE
t.ID IN
(
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) ;
Using EXISTS
SELECT * FROM yourtable t WHERE
EXISTS
(
SELECT 1 FROM (
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) s
WHERE s.id = t.id
);
Make use of the Between clause instead of specifying all unique ids:
SELECT ID FROM table WHERE ID BETWEEN 1 AND 2000 GROUP BY ID;
i you can create a table for these IDs and after use the condition of exist in the new table to get only your specific IDs

How to fill Joining date and id based on following requirement?

I want to fill the joining date and id by creating a new view and output should be like second image
you might be looking for something like:
UPDATE mytable
SET tofill.ID = fillvalues.ID
,tofill.JOININGDATE = fillvalues.JOININGDATE
FROM mytable tofill
INNER JOIN
( SELECT DISTINCT ID, JOININGDATE, NAME
FROM mytable
WHERE ID IS NOT NULL
AND JOININGDATE IS NOT NULL
) fillvalues
ON tofill.NAME = fillvalues.NAME
WHERE tofill.ID IS NULL
OR tofill.JOININGDATE IS NULL
;
I am not familiar with Oracle, but statement should be teh same or similiar

Returning distinct prioritizing results with order by

Name varchar, Value int, Active bit
-----------------------------------
'Name1',1,1
'Name2',2,1
'Name1',3,0
'Name2',4,0
'Name3',1,1
'Name4',1,1
I want to return where Active is anything but prioritize when it's 0 so I want to return this:
'Name1',3
'Name2',4
'Name3',1
'Name4',1
I tried this, but get an error to include Active in my return statement
Select Distinct Name, Value From Table Order by Active
So I tried this:
Select Distinct Name, Value, Active From Table Order by Active
But now it returns all the rows. I would like to prioritize where Active = 0 in the distinct results but since it requires I put Active in the return statement makes this complicated.
Can someone help?
Your question is a little confusing, but if I'm understanding it correctly, you need to use a group by statement:
select name,
max(case when active = 0 then value end) value
from yourtable
group by name
SQL Fiddle Demo
With your edits, you can use coalesce and still get it to work:
select name, coalesce(max(case when active = 0 then value end), max(value)) value
from yourtable
group by name
More Fiddle
You can order by fields not contained in the select clause
Select Name, Value
From Table
ORDER BY Active, Name, Value
But you cannot use SELECT DISTINCT at the same time.
If you use "select distinct" there is the possibility that some rows will be discarded, when this happens there is no longer any viable relationship retained between [Active] and the "distinct" rows. So if using select distinct, and you need to order by [Active], then [Active] MUST be in the select clause.
I couldn't delete the post b/c of the other answers, but here is answer I was looking for in case anyone else was wondering.
SELECT Distinct Name,Value FROM Table WHERE Active = 0
UNION ALL
SELECT Distinct Name,Value FROM Table a WHERE Active = 1 AND NOT EXISTS (
SELECT TOP 1 1 FROM Table a2 WHERE a2.Active = 0 AND a2.Name = a.Name
)
Review #Sgeddes 's answer for a better solution.
Thanks to everyone for their help.
Perhaps this:
create table #t(
Active int not null,
Name varchar(10) not null,
Value int not null,
primary key clustered (Active desc,Name,Value)
);
insert #t(Active,Name,Value)
select Active,Name,Value from [Table];
select Name, Value
from #t;
go
yields as desired:
Name Value
---------- -----------
Name1 1
Name2 2
Name3 1
Name4 1
Name1 3
Name2 4

SQL Server NULLABLE column vs SQL COUNT() function

Could someone help me understand something? When I can, I usually avoid (*) in an SQL statement. Well, today was payback. Here is a scenario:
CREATE TABLE Tbl (Id INT IDENTITY(1, 1) PRIMARY KEY, Name NVARCHAR(16))
INSERT INTO Tbl VALUES (N'John')
INSERT INTO Tbl VALUES (N'Brett')
INSERT INTO Tbl VALUES (NULL)
I could count the number of records where Name is NULL as follows:
SELECT COUNT(*) FROM Tbl WHERE Name IS NULL
While avoiding the (*), I discovered that the following two statements give me two different results:
SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL
The first statement correctly return 1 while the second statement yields 0. Why or How?
That's because
The COUNT(column_name) function returns the number of values (NULL
values will not be counted) of the specified column
so when you count Id you get expected result, while counting Name no, but the answer provided by query is correct
Everything is described in COUNT (Transact-SQL).
COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )
ALL - is default
COUNT(*) returns the number of items in a group. This includes NULL values and duplicates.
COUNT(ALL expression) evaluates expression for each row in a group and returns the number of nonnull values.
"COUNT()" does not count NULL values. So basically:
SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
will return the number of lines where ("ID" IS NOT NULL) AND ("Name" IS NULL); result is "1"
While:
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL
will count the lines where ("Name" IS NOT NULL) AND ("Name" IS NULL); result will always be 0
As it was said, COUNT (column_name) doesn't count NULL values.
If you don't want use COUNT(*) then use COUNT(1), but actualy you will not see difference in performance.
"Always avoid using *" is one of those blanket statements that people blindly follow. If you knew the reasons why you were avoiding * then you would know that none of those reasons apply when doing count(*).
The * in COUNT(*) is not the same * in SELECT * FROM...
SELECT COUNT(*) FROM T; very specifically means the cardinality of the table expression T.
SELECT COUNT(1) FROM T; will generate the same results as COUNT(*) but if the contents of the parentheses is not * then it must be parsed.
SELECT COUNT(c) FROM T; where c is a nullable column in table T will count the non-null values.
P.S. I'm comfortable with using SELECT * FROM... in the right circumstances.
P.P.S. Your 'table' has no key: consider INSERT INTO Tbl VALUES ('John', 'John', 'John', NULL, NULL, NULL); would be allowed by the results would be nonsense.

Count(*) with 0 for boolean field

Let's say I have a boolean field in a database table and I want to get a tally of how many are 1 and how many are 0. Currently I am doing:
SELECT 'yes' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 1
UNION
SELECT 'no' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 0;
Is there an easier way to get the result so that even if there are no false values I will still get:
----------
|yes | 3 |
|no | 0 |
----------
One way would be to outer join onto a lookup table. So, create a lookup table that maps field values to names:
create table field_lookup (
field int,
description varchar(3)
)
and populate it
insert into field_lookup values (0, 'no')
insert into field_lookup values (1, 'yes')
now the next bit depends on your SQL vendor, the following has some Sybase (or SQL Server) specific bits (the outer join syntax and isnull to convert nulls to zero):
select description, isnull(num,0)
from (select field, count(*) num from `table` group by field) d, field_lookup fl
where d.field =* fl.field
you are on the right track, but the first answer will not be correct. Here is a solution that will give you Yes and No even if there is no "No" in the table:
SELECT 'Yes', (SELECT COUNT(*) FROM Tablename WHERE Field <> 0)
UNION ALL
SELECT 'No', (SELECT COUNT(*) FROM tablename WHERE Field = 0)
Be aware that I've checked Yes as <> 0 because some front end systems that uses SQL Server as backend server, uses -1 and 1 as yes.
Regards
Arild
This will result in two columns:
SELECT SUM(field) AS yes, COUNT(*) - SUM(field) AS no FROM table
Because there aren't any existing values for false, if you want to see a summary value for it - you need to LEFT JOIN to a table or derived table/inline view that does. Assuming there's no TYPE_CODES table to lookup the values, use:
SELECT x.desc_value AS result,
COALESCE(COUNT(t.field), 0) AS num
FROM (SELECT 1 AS value, 'yes' AS desc_value
UNION ALL
SELECT 2, 'no') x
LEFT JOIN TABLE t ON t.field = x.value
GROUP BY x.desc_value
SELECT COUNT(*) count, field FROM table GROUP BY field;
Not exactly same output format, but it's the same data you get back.
If one of them has none, you won't get that rows back, but that should be easy enough to check for in your code.