Case function in MS SQL - sql-server

I have a table of format
id name flag
----------------
11 Jack 1
11 Jill 2
23 Joe 1
23 John 2
23 Sam 1
46 White 2
46 Dan 2
57 Dave 1
I am trying to return the table of format (based on the flag for particular id) like
id name_1 name_2
------------------
11 Jack Jill
23 Joe John
23 Sam John
46 NULL White
46 NULL Dan
57 Dave NULL
I tried this query but it does not give the expected result.
select id,
case flag when 1 then name end as name_1,
case flag when 2 then name end as name_2
from temp;

You want a join, not a select case. Something like this, assuming null is possible in either column:
SELECT a.id, a.name fname, b.name lname from
(SELECT id, name FROM temp WHERE flag = 1) a
full outer join
(SELECT id, name FROM temp WHERE flag = 2) b on a.id = b.id
Not sure what you expect in this case though:
46 NULL White
46 NULL Dan

I don't think you're going to be able to use case for this. This should do the trick, however:
select t1.id, t1.name as name_1, t2.name as name_2
from temp t1
inner join temp t2 on t1.id = t2.id and t1.flag = 1 and t2.flag = 2
I'm not sure you can get your partial result from the same query, so you could always do a union to find these...
select t1.id, t1.name as name_1, t2.name as name_2
from temp t1
inner join temp t2 on t1.id = t2.id and t1.flag = 1 and t2.flag = 2
union
select t1.id, t1.name as name_1, t2.name as name_2
from temp t1
left join temp t2 on t1.id = t2.id and t1.flag = 1 and t2.flag = 2
where t2.id is null
union
select t2.id, t1.name as name_1, t2.name as name_2
from temp t2
left join temp t1 on t1.id = t2.id and t1.flag = 1 and t2.flag = 2
where t1.id is null
This will get totally screwed up if there are 3 rows with the same ID :)

Related

SQL Not Exists include null value

I have two SQL Server tables :
Table 1
Id name description version
----------------------------------
1 Book1 Book 1 Title v1
2 Book2 Book 2 Title v2
3 Book3 Book 3 Title NULL
4 Book5 Book 5 Title v3
Table 2
Id name description version
----------------------------------
1 Book1 Book 1 Title v1
2 Book2 Book 2 Title v2
3 Book3 Book 3 Title NULL
4 Book4 Book 4 Title NULL
5 Book5 Book 5 Title NULL
I want to select all data from table 2 that doesn't exist in table 1 so I can
insert them into another table.
Here's the SQL query :
SELECT t2.name, t2.description, t2.version
FROM Table2 AS t2
WHERE
NOT EXISTS (SELECT t1.name, t1.description, t1.version
FROM Table1 as t1
WHERE t2.name = t1.name
AND t2.description = t1.description
AND t2.version = t1.version)
The result expected is this :
Id name description version
-----------------------------------
4 Book4 Book 4 Title NULL
5 Book5 Book 5 Title NULL
But I'm getting this instead:
Id name description version
---------------------------------
3 Book3 Book 3 Title NULL
4 Book4 Book 4 Title NULL
Why the null value are not evaluated in my NOT EXIST statement and are displayed?
NULL value when compare with anything will return FALSE. You will need to use IS NULL to handle
select t2.name, t2.description, t2.version
from Table2 as t2
WHERE NOT EXISTS
(
SELECT *
FROM Table1 as t1
WHERE t2.name = t1.name
AND t2.description = t1.description
AND (
t2.version = t1.version
OR (t2.version IS NULL AND t1.version IS NULL)
)
)
Optimized Query:
SELECT t2.name, t2.description, t2.version
FROM Table2 AS t2
LEFT JOIN Table1 AS t1
ON t2.name = t1.name
AND t2.description = t1.description
AND (t2.version = t1.version
OR (t2.version IS NULL AND t1.version IS NULL))
WHERE t1.ID is NULL
you can use EXCEPT for this problem.
you can use a common field from two tables and then select your data from that result.
look this following code :
SELECT name, description, version FROM Table2
EXCEPT
SELECT name, description, version FROM Table1
this code give you data that exist in table2 that not exist in table1.
You can use simply ISNULL() function:
SELECT t2.name, t2.description, t2.version
FROM Table2 AS t2
WHERE
NOT EXISTS (SELECT t1.name, t1.description, t1.version
FROM Table1 as t1
WHERE t2.name = t1.name
AND t2.description = t1.description
AND ISNULL(t2.version,0) = ISNULL(t1.version,0)

Avoid Cross Joins in SQL Server

I have 2 tables T1 and T2.
T1:
ID | Name
----+-------
A | A1
A | C1
T2:
ID | Name
-----+------
A | A1
A | B1
I want to retrieve records that have same ID and Name with flag 1 and Same ID and Different Name with flag 0. However, while joining the table in SQL Server, I am getting the a cross join which is:
A | A1 | A1 | 1
A | A1 | B1 | 0
A | C1 | A1 | 0
A | C1 | B1 | 0
But I need the answer as:
A | A1 | A1 | 1
A | C1 | B1 | 0
The above result is giving me the same information about name mismatch but in limited no. of rows and no repetition.
Could somebody let me know how can do this in SQL Server?
Is this what you're after:
SELECT T1.ID, T1.Name Name1, T2.Name Name2, case T1.Name when T2.Name then 1 else 0 end Result
from T1
inner join T2 on T1.ID = T2.ID
where T1.Name = T2.Name
or (not exists (select 1 from T2 where T1.Name = Name and T1.ID = ID)
and not exists (select 1 from T1 where T2.Name = Name and T2.ID = ID))
Use a union to keep things simple:
select T1.ID, T1.Name Name1, T2.Name Name2, 1 flag
from T1
join T2 on T1.ID = T2.ID
and T1.Name = T2.Name
union all
select T1.ID, T1.Name, T2.Name, 0
from T1
join T2 on T1.ID = T2.ID
and T1.Name != T2.Name
Using a union is not the most efficient way, but it’s much easier to understand and unless you have millions of rows, it will still run very fast (and union all is quite a bit faster than union)
you can use ROW_NUMBER and FULL JOIN
DECLARE #T1 TABLE (ID VARCHAR(5), Name VARCHAR(5))
INSERT INTO #T1 VALUES ('A', 'A1')
INSERT INTO #T1 VALUES('A', 'C1')
DECLARE #T2 TABLE (ID VARCHAR(5), Name VARCHAR(5))
INSERT INTO #T2 VALUES ('A', 'A1')
INSERT INTO #T2 VALUES ('A', 'B1')
SELECT T1.ID, T1.Name, T2.Name, CASE WHEN T1.Name = T2.Name THEN 1 ELSE 0 END
FROM
( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM #T1 ) T1
FULL JOIN
( SELECT ROW_NUMBER()OVER(PARTITION BY ID ORDER BY Name) AS RN, * FROM #T2 ) T2
ON T1.ID = T2.ID AND T1.RN = T2.RN
Result:
ID Name Name
----- ----- ----- -----------
A A1 A1 1
A C1 B1 0

how to join 4 table into single table?

table-1
name closedid
rere 4
trtr 5
ewew 6
And
table-2
name openedid
rere 6
trtr 7
ytyt 8
uyuy 5
And
table-3
name assign
rere 6
ytyt 8
uyuy 5
rtyy 9
And
table-4
name unassign
rere 6
trtr 7
errt 5
hdtg 9
I want final output like this:
name closedid opened assign unassign
rere 4 6 6 6
trtr 5 7 null 7
ytyt null 8 8 null
uyuy null 5 5 null
ewew 6 null null null
rtyy null null 9 null
errt null null null 5
hdtg null null null 9
I think, this is what you are looking for:
SELECT coalesce(t1.NAME, t2.NAME, t3.NAME, t4.NAME) NAME
,t1.closedid
,t2.openedid
,t3.assign
,t4.unassign
FROM [table-1] t1
FULL OUTER JOIN [table-2] t2 ON t1.NAME = t2.NAME
FULL OUTER JOIN [table-3] t3 ON isnull(t1.NAME, t2.NAME) = t3.NAME
FULL OUTER JOIN [table-4] t4 ON coalesce(t1.NAME, t2.NAME, t3.NAME) = t4.NAME
I would grab all the distinct names and then do left joins with that list, would make it easier to understand what's going on.
;WITH cte(name)
AS (
SELECT name FROM table1
UNION
SELECT name FROM table2
UNION
SELECT name FROM table3
UNION
SELECT name FROM table4
)
SELECT
cte.name,
table1.closedid,
table2.openid,
table3.assign,
table4.unassign
FROM
cte
LEFT JOIN table1 ON cte.name = table1.name
LEFT JOIN table2 on cte.name = table2.name
LEFT JOIN table3 on cte.name = table3.name
LEFT JOIN table4 on cte.name = table4.name
SQLFiddle
Use UNION to get your distinct list of names
Use LEFT JOIN to retrieve your data
Example:
SELECT list.name, t1.assigned, t2.unsassigned, t3.closed, t4.open
FROM
(select name from table1
union select name from table2
union select name from table3
union select name from table4
) list
LEFT JOIN table1 t1 ON (list.name = t1.name)
LEFT JOIN table2 t2 ON (list.name = t2.name)
LEFT JOIN table3 t3 ON (list.name = t3.name)
LEFT JOIN table4 t4 ON (list.name = t4.name)
select
n.name, t1.closedid, t2.openedid, t3.assign, t4.unassign
from
(select name from [table-1]
union
select name from [table-2]
union
select name from [table-3]
union
select name from [table-4]
) as n
left join [table-1] t1 on n.name = t1.name
left join [table-2] t2 on n.name = t2.name
left join [table-3] t3 on n.name = t3.name
left join [table-4] t4 on n.name = t4.name
select coalesce(t1.name,t2.name,t3.name,t4.name) name, t1.closeid, t2.openid, t3.assign, t4.unassign
from table-1 t1
full outer join table-2 t2 on t1.name = t2.name
full outer join table-3 t3 on t2.name = t3.name
full outer join table-4 t4 on t3.name = t4.name

Conditional Inner Join in Oracle

I have an issue regarding conditional inner join. Kindly have a look at the following sqlfiddle.
http://sqlfiddle.com/#!4/6dc88
Here i'm trying to get all the same name. but if in case the id is 1 then also get the same name and the name which has id of 0. Your help will be appriciated. thanks. here is the example
Table1
Id | Name
1 | A
2 | B
3 | C
Table2
Id | Name
1 | a
2 | b
3 | c
0 | d
Here is what i expect
A | a
B | b
C | c
A | d
Edit: Sorry i forget to mention my query, here is what i have tried so far..
select t1.name, t2.name from table1 t1
inner join table2 t2 on
CASE
WHEN t1.id = t2.id_copy and t1.id = 1 THEN
0
else
t1.id
END = t2.id_copy
Thanks in advance.
Assuming you mean that if table2.id is 0 then it should match with table1.id = 1, then this should do the trick:
with table1 as (select 1 id, 'A' name from dual union all
select 2 id, 'B' name from dual union all
select 3 id, 'C' name from dual),
table2 as (select 1 id, 'a' name from dual union all
select 2 id, 'b' name from dual union all
select 3 id, 'c' name from dual union all
select 0 id, 'd' name from dual)
select t1.name, t2.name
from table1 t1
inner join table2 t2 on (t1.id = case when t2.id = 0 then 1 else t2.id end);
NAME NAME_1
---- ------
A a
B b
C c
A d
If there's more complicated logic around what decides how non-matching (t1.id = t2.id) rows in table2 match with table1, then you'll have to explain the logic.
Personally I would prefer to use something simpler, like:
select t1.name, t2.name from table1 t1
inner join table2 t2
on t1.id = t2.id_copy or (t1.id = 1 and t2.id_copy = 0)

How to use SQL(Max) function

I have 2 tables
Table 1:
id name adress
1 John New York
2 Jane London`
... and so on
Table 2:
id fila date
1 43 01/01/2010
1 39 10/01/2011
1 55 23/12/2012
2 10 01/01/2008
2 15 02/02/2010`
.... and so on
I want to get data like this
id fila name adress date
-----------------------------------------
1 55 John New York 23/12/2012
2 15 Jane London 02/02/2010
..... and so on.
Thanks
ok. what you are really looking for is "What is the latest date in table2 for each of my rows in Table1". So to answer the question:
select *
From Table1
inner join (
select id, max(fila) as maxfila
from Table2
group by id
) as maxdates
on Table1.id = maxdates.id
inner join Table2 on Table2.id = maxdates.id AND Table2.fila = maxdates.maxfila
Try this:
;with cte as
(select id, max(fila) maxfila
from table2
group by id)
select t1.id, t1.name, t1.address, t2.fila, t2.date
from table1 t1
left join table2 t2 on t1.id = t2.id
inner join cte c on t1.id = c.id
where t2.fila = c.maxfila
Try this
Select t1.id, t1.name, t1.address, t2.maxfila
from table1 t1
left outer join
(select id, max(fila) maxfila
from table2
group by id) t2
select t1.id, t1.name t1.address, max(t2.fila),
(select top 1 date from table2 order by fila desc where table2.id = t1.id)
from table1 t1 inner join
table2 t2 on t1.id = t2.id

Resources