Return different rows between two tables - sql

Is there a way to check and return all rows that are not common between two tables?
Table 1:
pk name date
102 John 1/1/16
101 Bob 1/1/17
Table 2:
pk name date
102 John 1/1/16
104 Bob 1/1/17
105 Ted 1/1/18
Ideally, I can also limit the query by date. So If I limit by Date < 1/1/18, the result would be:
table pk name date
1 101 Bob 1/1/17
2 104 Bob 1/1/17

select * from table1
union
select * from table2
except
(select * from table1 intersect select * from table2)

select * from table1 t1
where not exsits (
select 1 from table2 t2 where t2.pk = t1.pk
) and t1.Date < '2018/1/1'
union all
select * from table2 t2
where not exsits (
select 1 from table1 t1 where t2.pk = t1.pk
) and t2.Date < '2018/1/1'

You can use EXCEPT for this like
select pk,
name,
date from table1
except
select pk,
name,
date from table2;
(OR) using NOT IN operator along with UNION like
select * from table1 where pk not in (select distinct pk from table2);
union
select * from table2 where pk not in (select distinct pk from table1);

To be more precise with your sample data:
SELECT * FROM
(( SELECT 1 as [table],* FROM
(SELECT * FROM #TABLE_1
EXCEPT
SELECT * FROM #TABLE_2) AS Inner1)
UNION
(SELECT 2 as [table],* FROM
(SELECT * FROM #TABLE_2
EXCEPT
SELECT * FROM #TABLE_1) AS Inner2)) AS Final
WHERE Final.date < '2018-01-01'

Related

sql select values from another table if exist

Please help, need to select from table 1, but if entry with the same id exists in table2 should return name and last name from there otherwise values from table1
table1
id|name|lastname
1 | |
2 | |
3 | |
table2
id|name|lastname
3 | |
Tried this, but not working
SELECT ID, NAME, LASTNAME
FROM table1
WHERE EXISTS
(SELECT 1 FROM table2 WHERE table2.ID = table1.ID)
if entry with the same id exists in table2 should return name and last name from there otherwise values from table1
You want a LEFT OUTER JOIN and then to use COALESCE:
SELECT t1.id,
COALESCE( t2.name, t1.name ) AS name,
COALESCE( t2.lastname, t1.lastname ) AS last_name
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON ( t1.id = t2.id )
Which, for your sample data:
CREATE TABLE table1 ( id, name, lastname ) AS
SELECT 1, 'Alice1', 'Abbot1' FROM DUAL UNION ALL
SELECT 2, 'Betty1', 'Baron1' FROM DUAL UNION ALL
SELECT 3, 'Carol1', 'Casey1' FROM DUAL;
CREATE TABLE table2 ( id, name, lastname ) AS
SELECT 3, 'Carol2', 'Casey2' FROM DUAL;
Outputs:
ID
NAME
LAST_NAME
3
Carol2
Casey2
2
Betty1
Baron1
1
Alice1
Abbot1
db<>fiddle here

SQL joining on max ID or dates between date

I have the following tables:
Table 1:
with two columns (PatientID,Name)
Table 2:
with four columns (ID,PatientID,FromDate,ToDate)
I need to join (left join) table1 to table2 (on patientid) to get the values in table2 that has getdate() within Fromdate and todate and if there is no such record, then get the latest id.
I am using SQL 2016.
Table 1 Data:
1 Peter
2 Fady
Table 2 data
1 2019-01-01 2019-02-01
1 2019-03-01 2019-04-01
2 2019-06-01 2019-12-01
2 2020-01-01 2020-01-01
I should get:
1 2019-03-01 2019-04-01
2 2019-06-01 2019-12-01
I think apply does what you want. I think you simply want:
select t1.*, t2.*
from table1 t1 outer apply
(select top (1) t2.*
from table2 t2
where t2.patientid = t.patientid
order by fromdate desc
) t2;
I am guessing that you don't have future fromdates. If you do, then the order by can be tweaked to handle this.
EDIT:
If you can have future dates, then this would be tweaked to:
select t1.*, t2.*
from table1 t1 outer apply
(select top (1) t2.*
from table2 t2
where t2.patientid = t.patientid
order by (case when getdate() >= fromdate and getdate < todate() then 1 else 2 end), id desc
) t2;
You can use a temp table. First get the matching data, then update the missing IDs with the Max(Id) as below:
select table1.*, table2.ID
into #temp
from table1 t1
left outer join table2 t2 on t1.PatientID = t2.PatientID
where getdate() between t2.fromdate and t2.todate
update t
set ID = (select max(ID) from table2 t2 where t.PatientID=t2.PatientID)
from #temp t
where t.ID is null
select * from #temp
You can do a union, only one part will have value:
;WITH cte(ID,PatientID,FromDate,ToDate)
AS
(
SELECT t2.ID,t2.PatientID,t2.FromDate,t2.ToDate
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.PatientID=t2.PatientID
WHERE t2.FromDate >=GETDATE() AND t2.Todate<=GETDATE()
),
cte1 (ID)
AS
(
SELEC TMAX(ID) FROM Table2 WHERE NOT EXISTS(SELECT 1 FROM cte)
)
SELECT ID,PatientID,FromDate,ToDate
FROM cte
UNION ALL
SELECT ID,NULL,NULL,NULL
FROM cte1

retrieving ids with 'only' one type of code

Sample of table:
ID Code
2324 1
2324 2
2325 1
2326 1
2326 2
I want to get the id’s that only have code ‘1’ and not also code ‘2’ so the result would be
2325 1
Since the others have code’s 1 and 2
I've tried
SELECT * FROM TABLE
WHERE CODE != 1 AND CODE = 2
but that just returns any id's with code 2 regardless if the id also has code 1 or not
select ID, min(code) from t1
group by ID
having min(code) = 1 and max(code) = 1
With NOT EXISTS:
SELECT * FROM TABLE T
WHERE T.Code = 1 AND NOT EXISTS (
SELECT 1 FROM TABLE WHERE ID = T.ID AND Code <> T.Code
)
Try this:
select * from myTable t1
where not exists(select 1 from myTable
where t1.id = id and Code <> 1)
use not exists
select * from table t1 where Not exists
( select 1 from table t2 where t1.id=t2.id and
t2.code=2)
with cte as
(
select 2324 as id ,1 as code union all
select 2324 ,2
union all
select 2325,1
union all
select 2326,1 union all
select 2326 ,2
)
select * from cte t1 where Not exists
( select 1 from cte t2 where t1.id=t2.id and
t2.code=2)
demo link
id code
2325 1
You can try this.
SELECT * FROM TABLE
WHERE T.Code = 1 AND NOT EXISTS (
SELECT 1 FROM TABLE WHERE ID = T.ID AND Code <> T.Code
)

multiple select in sql server

I want to search between 2 tables but that field i want to search is foreign key in other table
my tables are like this:
table 1
ID TitleSR
1 888
2 999
table 2
ID TitleSR
1 11
2 22
3 33
4 44
table contain value
ID value
11 italy
22 swiss
888 lilium
999 mount
33 england
I think I understand you. Try this one:
Select *
From table3 as VCT Inner Join
(Select * From table1
Union
Select * From table2) as FGT
On VCT.ID = FGT.TitleSR
Where value = 'italy';
You can use either of these methods:
Returns only t1 fields
SELECT * FROM Table1 t1
WHERE t1.ID in (SELECT ID FROM Table2);
Returns ALL fields
SELECT * FROM Table1 t1
JOIN Table2 t2 on t1.ID = t2.ID;
If your 'values' exist in a separate table (tblValues), you can use any of these:
Returns tblValues fields
SELECT * FROM tblValues tval
WHERE tval.ID in (SELECT TitleSR FROM Table1);
returns ALL fields
SELECT *
FROM (tblValues tval
JOIN Table1 t1 on tval.ID = t1.TitleSR)
JOIN Table2 on tval.ID = Table2.TitleSR;

How to select in SQL Server 2008

Have an issue
Examle
ID ID2
1 100
3 100
5 100
1 110
2 110
4 110
select * from table where ID in (1,4) ---executing not correctly
select * from table where ID = '1' and ID = '4' ---not work
I need that ID2 will '110' (select ID2 which have 2 value ID)
Thanks.
If you have few ID's you can use EXISTS:
SELECT ID, ID2
FROM dbo.Table1 t1
WHERE EXISTS
(
SELECT 1 FROM dbo.Table1 t2
WHERE t2.ID=1 AND t2.ID2=t1.ID2
)
AND EXISTS
(
SELECT 1 FROM dbo.Table1 t2
WHERE t2.ID=4 AND t2.ID2=t1.ID2
)
AND ID IN (1, 4)
This returns the two records that have the same ID2 and ID=1 AND ID=4.
ID ID2
1 110
4 110
Demo-Fiddle
SELECT ID FROM (
SELECT ID, COUNT(*) OVER(PARTITION BY ID2) as cnt FROM Table) t
WHERE t.cnt>1