I have two tables, each with the following fields: IDnumber, SectionNumber, Date. There is overlapping information in the two tables.
How do I select only rows that do NOT overlap (ie. in one table but not the other)?
You can use a NOT IN in your WHERE clause.
SELECT IDnumber, SectionNumber, Date
FROM table1
WHERE IDnumber NOT IN (SELECT IDnumber FROM table2)
OR NOT EXISTS
SELECT IDnumber, SectionNumber, Date
FROM table1 t1
WHERE NOT EXISTS (SELECT IDnumber FROM table2 t2 WHERE t1.IDnumber = t2.IDnumber)
Which DBMS?
If SQL Server, then it's almost what you wrote in the title...
SELECT *
FROM Table1
WHERE IDnumber NOT IN (SELECT IDnumber FROM Table2)
If you want to compare multiple columns, you need an outer join:
select table1.*
from table1 left outer join
table2
on table1.id = table2.id and
table1.SectionNumber = table2.SectionNumber and
table1.date = table2.date
where table2.id is null
In the case where you might have many matches between the tables, then the join can be inefficient. Assuming you only want those three fields, you can use a trick that avoids the join:
select id, SectionNumber, date
from ((select 0 as IsTable2, id, SectionNumber, date
from table1
) union all
(select 1 as IsTable2, id, SectionNumber, date
from table2
)
) t
group by id, SectionNumber, date
having max(isTable2) = 0
SELECT *
FROM Table1 t1 left join Table2 t2
on t1.id=t2.id
where t2.id is null
Related
I'm looking for help structuring a SQL query with a subquery on table2 based on a column in table1, but where table1 and table2 have no relation.
something like
SELECT name, address, dateCreated,
(SELECT itemId FROM table2 WHERE itemDate BETWEEN dateCreated AND DATEADD(ss,10,dateCreated) as item
FROM table1
So for each row 'item' must be selected from table2 based on dateCreated for that row.
You can try using IF EXISTS as shown below.
SELECT name
, [address]
, dateCreated
FROM table1
where exits(
SELECT itemId
FROM table2 WHERE itemDate BETWEEN dateCreated AND DATEADD(ss, 10,dateCreated) and table1.ItemId = table2.ItemId)
SELECT name, address, dateCreated, table2.itemId
from table1 LEFT JOIN table2 WHERE itemDate BETWEEN dateCreated AND DATEADD(ss,10,dateCreated)
If you want at most one item from table2, then your approach is fine but you want top (1):
SELECT t1.name, t1.address, t1.dateCreated,
(SELECT TOP (1) t2.itemId
FROM table2 t2
WHERE t2.itemDate BETWEEN t1.dateCreated AND DATEADD(second, 10, t1.dateCreated
) as item
FROM table1 t1;
You can also phrase this as a lateral join, using outer apply:
SELECT t1.name, t1.address, t1.dateCreated,
t2.itemId
FROM table1 t1 OUTER APPLY
(SELECT TOP (1) t2.itemId
FROM table2 t2
WHERE t2.itemDate BETWEEN t1.dateCreated AND DATEADD(second, 10, t1.dateCreated
) t2;
This makes it easy to select multiple columns.
Can you please try this below logic? The way tried, will through ERROR if there are more than one records found in table2 against any row from table1.
SELECT A.name,
A.address,
A.dateCreated,
B.itemId
FROM table1 A
INNER JOIN table2 B
ON B.itemDate BETWEEN A.dateCreated AND DATEADD(ss,10,A.dateCreated)
With the above query, you will get N numbers of row for each row in table1 based the logic applied for Date --BETWEEN A.dateCreated AND DATEADD(ss,10,A.dateCreated)
I have a table:
My select:
select regexp_split_to_table(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
order by s
Or also I can get a string '22173345566179111134546175622323811' with this:
select string_agg(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
I need to get a table with number|count data, I mean for any number to get a count of repetitions in the select, for example:
1 | 9
2 | 5
3 | 5
and so on..
PostgreSQL DBMS
Does this do what you want?
select id, count(*)
from (select t1."Id" from table1 t1
union all
select t2."Id" from table2 t2
) t3
group by id
order by id;
If I understand you right, you want a list of all digits, that exist in a set of IDs from two tables and the count of each digit, how often it appears in all these IDs. If so, you just need to GROUP BY a digit and use count().
SELECT s.d,
count(*) count
FROM (SELECT t1."Id"
FROM table1 t1
UNION ALL
SELECT t2."Id"
FROM table2 t2) t3
CROSS JOIN LATERAL regexp_split_to_table(t3."Id"::character varying, '') s(d)
GROUP BY s.d
ORDER BY s.d;
easiest way
select regexp_split_to_table(t3."Id"::character varying,'') s, count(*) count
from (select t1."Id" from table1 t1 union all select t2."Id"from table2 t2) t3
group by s
In the table1 I have 1421144 rows and table2 has 1421134 rows.
I tried this query, but I don't get any rows returned.
select table1.ID
from table1
where ID not in (select ID from table2)
I have also used this query:
select ID from table1
except
select ID from table2
But I don't get any rows. Please help me, if the table1 has duplicates how can I get those duplicates?
Assuming ids are unique, you can use full outer join in either database:
select coalesce(t1.id, t2.id) as id,
(case when t1.id is null then 'T2 only' else 'T1 only' end)
from t1 full outer join
t2
on t1.id = t2.id
where t1.id is null or t2.id is null;
It is quite possible that the two tables have the same sets of ids, but there are duplicates. Try this:
select t1.id, count(*)
from t1
group by t1.id
having count(*) > 1;
and
select t2.id, count(*)
from t2
group by t2.id
having count(*) > 1;
If you have duplicates, try:
WITH Dups AS(
SELECT ID, COUNT(ID) OVER (PARTITION BY ID) AS DupCount
FROM Table1)
SELECT *
FROM Dups
WHERE DupCount > 1;
If you need to delete the dups, you can use the following syntax:
WITH Dups AS(
SELECT ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS DupCount
FROM Table1)
DELETE FROM Dups
WHERE DupCount > 1;
Obviously, however, check the data before you run a DELETE statement you got from a random on the internet. ;)
I Guess u have data type mismatch between 2 tables, cast them to integers and try your first query
select table1.ID from table1
where cast(ID as int) not in (select cast(ID as int) from table2)
If you have stored in a different format than int, cast them to varchar and
try with this datatype.
Not in takes longer to execute, use left join instead
select t1id from
(
select t1.id t1Id, t2.Id t2Id from table1 left join table2
on cast(t1.id as int) = cast(t2.id as int)
) x where t2Id is null
i use these code SELECT id , date
FROM table1
UNION ALL
SELECT id ,k1'
FROM ork9
group by id
ORDER BY k1,k3 ASC
but the recode Duplicate
union will be not good option try this
select table2.id,table1.date from table2
left join table1 on table1.id = table2.id
This will return your expected result
SELECT t2.id, t1.date FROM table1 t1 right join table2 t2 on t1.id=t2.id
This will join the two tables and bring all records from table2 and only dates from table1
. I need to find only Employees that are type A. I know this can be done with a JOIN. Then I need to get a count of all distinct EMP_ID for each Region.Also note this will be done in Oracle
These are basic things, you need join and condition on the table containing type = 'A':
select count(distinct emp_id)
from table1 t1
join table2 t2 on t1.job_code = t2.job_code
where t2.type = 'A'
group by t1.region
Could use a CTE.
With someCte
as
(
Select * from table1 t1
Inner join table2 t2 on t1.Job_code = t2.Job_code
where t1.type like 'A' and t2.type like 'A'
)
select distinct emp_id from someCte