Select rows from two tables only whenn 'all in' - sql

I've got the following tables
Table1
Col1 | Col2
r1c1 | r1c2
r2c1 | r2c2
r3c1 | r3c2
r4c1 | r4c2
Table2
Col1_Table1 | Col2
r1c1_table1 | r1c2
r2c1_table1 | r2c2
r3c1_table1 | r3c2
So you see my row #4 is missing in Table2.
Select all rows from table 1 and join table 2. No Problem
But what looks the select like when I want to select all from Table1 but only if all from Table1 are in Table2? I hope you can understand.
In my example I the result of the select has to be zero/null.

If I understand you correctly, you want to return all rows of table 1 only if all of table 1 also exists in table 2
So in effect:
SELECT * FROM #table1
WHERE
(SELECT COUNT(*) FROM #table1)
= (SELECT COUNT(*) FROM #Table1 INNER JOIN #Table2 ON #Table1.col1 = #Table2.col1)
Is that correct? in which case a better way of doing this would be:
SELECT *
FROM #table1
WHERE NOT EXISTS (
SELECT 1
FROM #table1
WHERE col1 NOT IN (SELECT col1 FROM #table2)
);

Hi Please see example below
IF OBJECT_ID('tempdb..#Table1') IS NOT NULL
BEGIN
DROP TABLE #Table1
END
IF OBJECT_ID('tempdb..#Table2') IS NOT NULL
BEGIN
DROP TABLE #Table2
END
CREATE TABLE #Table1 (
Col1 NVARCHAR(20)
, Col2 NVARCHAR(20)
)
INSERT INTO #Table1 VALUES ('r1c1', 'r1c2')
INSERT INTO #Table1 VALUES ('r2c1', 'r2c2')
INSERT INTO #Table1 VALUES ('r3c1', 'r3c2')
INSERT INTO #Table1 VALUES ('r4c1', 'r4c2')
CREATE TABLE #Table2 (
Col1_Table1 NVARCHAR(20)
, Col2 NVARCHAR(20)
)
INSERT INTO #Table2 VALUES ('r1c1_table1','r1c2')
INSERT INTO #Table2 VALUES ('r2c1_table1','r2c2')
INSERT INTO #Table2 VALUES ('r3c1_table1','r3c2')
SELECT COUNT(*) as 'Result'
FROM #Table1 AS t1
INNER JOIN #Table2 AS t2
ON t1.Col1 = t2.Col2
IF OBJECT_ID('tempdb..#Table1') IS NOT NULL
BEGIN
DROP TABLE #Table1
END
IF OBJECT_ID('tempdb..#Table2') IS NOT NULL
BEGIN
DROP TABLE #Table2
END
Hope it helps

I think you are looking for INTERSECT.
Ex:
select Col1, Col2 from table1
INTERSECT
select Col1, Col2 from table2
Intersect will return results based on data being in BOTH tables.
Reference: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-except-and-intersect-transact-sql?view=sql-server-2017

Related

Update statement with Where Not Exists

I am trying to do the following:
Set the status column to 1 when the row in the first table (variable) does not exist in the second one.
I tried this:
update #table1
set status=1
where NOT EXISTS (select top 1 1 from #table2 where #table1.foo=#table2.foo)
But this doesn't even compile, not recognizing #table1 in the Where statement.
Must declare the scalar variable "#table1".
Any clue about this?
Your approach is fine. You just need table aliases because the # is used to in SQL Server to represent variables (scalars or tables) and is hence problematic for aliases:
update t1
set status = 1
from #table1 t1
where not exists (select 1 from #table2 t2 where t2.foo = t1.foo);
Note that the top 1 is unnecessary in the subquery.
You can do this kind of thing by joining the two tables with a LEFT JOIN and checking the right side for NULL:
UPDATE t1
SET t1.status=1
FROM #table1 t1
LEFT JOIN #table2 t2
ON t1.foo = t2.foo
WHERE t2.foo IS NULL
The specific error you got is because you haven't got a statement declaring #table1 as a table variable, like DECLARE #table1 TABLE (foo int) for example. If table1 is not a variable, you don't need the #.
no need any top inside scaler query
update #table1
set status=1
where NOT EXISTS (select 1 from #table2 where #table1.foo=#table2.foo)
cause exists return boolean
you could use below query
update #table1
set status=1
where #table1.foo not in ( select foo from #table2 where foo is not null)
There are multiple ways - inner query with NOT IN and NOT EXISTS and JOIN query:
update tab1 set status = 1 where name not in (select name from tab2);
update tab1 set status = 1 where not exists (select 1 from tab2 where tab1.name=tab2.name);
update tab1 set status = 1 from tab1 left outer join tab2 on tab1.name = tab2.name where tab2.name is null;
Sample schema to run above queries;
create table tab1(name varchar(30), status int);
create table tab2(name varchar(30));
insert into tab1 values('a', 5);
insert into tab1 values('b', 6);
insert into tab1 values('c', 7);
insert into tab1 values('d', 8);
insert into tab2 values('a');
insert into tab2 values('d');
You have to declare table1 and table2 variables
DECLARE #table1 YOUR_TABLE1_NAME;
DECLARE #table2 YOUR_TABLE2_NAME;
update #table1
set status=1
where NOT EXISTS (select top 1 from #table2 where #table1.foo=#table2.foo)
You should use alias name for both table.
DECLARE #TABLE_1 TABLE (DEPT_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_1(DEPT_NAME,DEP_ID)
SELECT 'IT',1 UNION ALL
SELECT 'HR',2 UNION ALL
SELECT 'ACCOUNT',3 UNION ALL
SELECT 'ADMIN',4 UNION ALL
SELECT 'SALES',5 UNION ALL
SELECT 'CEO',7
DECLARE #TABLE_2 TABLE (E_ID INT,EMP_NAME VARCHAR(50),DEP_ID INT)
INSERT INTO #TABLE_2(E_ID,EMP_NAME,DEP_ID)
SELECT 1,'JHON',1 UNION ALL
SELECT 2,'LITA',2 UNION ALL
SELECT 3,'MATT',1 UNION ALL
SELECT 4,'JEFF',1 UNION ALL
SELECT 5,'BROCK',2 UNION ALL
SELECT 6,'BOB',5 UNION ALL
SELECT 7,'SAM',4 UNION ALL
SELECT 8,'DAVID',3 UNION ALL
SELECT 9,'JACK',1 UNION ALL
SELECT 10,'GARY',4 UNION ALL
SELECT 11,'DONALD',6
SELECT * FROM #TABLE_1 A WHERE NOT EXISTS (SELECT DEP_ID FROM #TABLE_2 B WHERE A.DEP_ID=B.DEP_ID )

Match the codes and copy columns

I am working in SQL Server 2008. I have 2 tables Table1 & Table2.
Table1 has columns
SchoolCode, District, Type, SchoolName
and Table2 has columns
SchoolCode1, District1, Type1, SchoolName1
SchoolCode columns in both tables have the same codes like "1234"; code is the same in both schoolcode columns.
Now I want to copy the District, Type and SchoolName column values from Table1 to Table2 if SchoolCode in both tables is same.
I think the query will use join but I don't know how it works. Any help on how I can do this task?
Maybe use an update statement in join if by copying over you mean updating rows
update t2
set
District1= District,
Type1= Type,
SchoolName1= SchoolName
from Table1 t1
join
Table2 t2
on t1.SchoolCode=t2.SchoolCode1
I could give you a little bit of idea. here is it:
Insert into table2 (District1, Type1, SchoolName1)
SELECT District, Type, SchoolName
FROM table1
where table1.Schoolcode=table2.Schoolcode1
You have to use Inner join to update data from table 1 to table 2, Inner join will join values that are equal. . To learn more about joins, I highly recommend you to read the below article
SQLServer Joins Explained - W3Schools
Please refer the below code, for the convenience I have used the temporary tables..
DECLARE #Table1 TABLE
(
SchoolCode INT,
District VARCHAR(MAX),
Type VARCHAR(MAX),
SchoolName VARCHAR(MAX)
)
DECLARE #Table2 TABLE
(
SchoolCode1 INT,
District1 VARCHAR(MAX),
Type1 VARCHAR(MAX),
SchoolName1 VARCHAR(MAX)
)
INSERT INTO #Table1
( SchoolCode ,District , Type , SchoolName
)
VALUES ( 1 ,'DIS1' ,'X' ,'A'),
( 2 ,'DIS2' ,'Y' ,'B'),
( 3 ,'DIS3' ,'Z' ,'C'),
( 4 ,'DIS4' ,'D' ,'D'),
( 5 ,'DIS5' ,'K' ,'E')
INSERT INTO #Table2
( SchoolCode1 ,District1 , Type1 , SchoolName1
)
VALUES ( 1 ,'DIS1' ,'X' ,'A'),
( 2 ,NULL ,'Z' ,NULL),
( 3 ,'DIS3' ,'Z' ,'C'),
( 4 ,NULL ,'Z' ,'S'),
( 5 ,'DIS5' ,'K' ,'E')
--BEFORE
SELECT * FROM #Table1
SELECT * FROM #Table2
--Logic UPDATE Table 2
UPDATE t2 SET t2.District1 = t1.District,
t2.Type1 = t1.Type,
t2.SchoolName1 = t1.SchoolName
FROM #Table1 t1
INNER JOIN #Table2 t2 ON t1.SchoolCode = t2.SchoolCode1
-- End Logic UPDATE Table 2
--AFTER
SELECT * FROM #Table1
SELECT * FROM #Table2
You can join tables in an UPDATE statement.
Note, I have aliased the tables, table1 and table2 as t1 and t2 respectively.
This is what I did:
create table Table1
(SchoolCode varchar(50),
District varchar(50),[Type] varchar(50),SchoolName varchar(50))
go
create table Table2
(SchoolCode1 varchar(50), District1 varchar(50),[Type1] varchar(50),SchoolName1 varchar(50))
go
insert into table1 values ('1234','District1','High','Cool School')
insert into table1 values ('2222','District2','Lower','Leafy School')
insert into table2 (SchoolCode1) values ('1234')
go
update t2
set District1 = District,
Type1 = [Type],
SchoolName1 = SchoolName
from table1 t1
join table2 t2
on t2.SchoolCode1 = t1.SchoolCode
go
select * from table2
go

SQL inserted value of a table as column of another table

Table1 Table2
Id Name Id Table1Id Value
1 Some 1 1 value1
2 Some1 2 2 value2
3 Some2 3 3 value3
4 Some3
.
.
I want to result this:
Some Some1 Some2 Some3
value1 value2 value3 NULL
When I entered value into the Table1 I want to look like the table2's column, how can I do this?
I guess I'm looking for pivot query.
Thanks for posting the additional information. Based on what you said, you're looking for a PIVOT statement that will turn each name in Table1 into a column header, containing the corresponding value from Table2.
Have a look at the following SQL, which produces the output your sample data indicates.
CREATE TABLE #Table1 (ID INT, Name varchar(5))
CREATE TABLE #Table2 (ID INT, Table1ID INT, Value varchar(6))
INSERT INTO #Table1 (ID, Name) SELECT 1, 'Some'
INSERT INTO #Table1 (ID, Name) SELECT 2, 'Some1'
INSERT INTO #Table1 (ID, Name) SELECT 3, 'Some2'
INSERT INTO #Table1 (ID, Name) SELECT 4, 'Some3'
INSERT INTO #Table2 (ID, Table1ID, Value) SELECT 1, 1, 'Value1'
INSERT INTO #Table2 (ID, Table1ID, Value) SELECT 2, 2, 'Value2'
INSERT INTO #Table2 (ID, Table1ID, Value) SELECT 3, 3, 'Value3'
-- List of values to be columns
declare #cols nvarchar(max)
select #cols = coalesce(#cols+N',', N'') + quotename(Name) from #Table1 order by ID
PRINT #Cols
declare #query varchar(MAX)
SET #query = '
SELECT *
FROM
(
SELECT T1.Name, T2.Value
FROM
#Table1 T1
INNER JOIN
#Table2 T2 ON
T1.ID = T2.Table1ID
) s
PIVOT
(
MAX(Value) FOR Name IN ('+#Cols+')
) p'
PRINT #query
EXEC (#query)
DROP TABLE #Table1
DROP TABLE #Table2

Need to fetch records from one table which is not present in another one table

I have two tables, one table has three columns another one has two columns. I need to fetch records from Table1 which is not present in Table2. For example
DECLARE #Table1 TABLE (C1 INT, C2 INT, C3 INT)
INSERT INTO #Table1 VALUES(1,1,1)
INSERT INTO #Table1 VALUES(1,2,2)
INSERT INTO #Table1 VALUES(1,3,3)
INSERT INTO #Table1 VALUES(2,1,4)
DECLARE #Table2 TABLE (C1 INT, C2 INT)
INSERT INTO #Table2 VALUES(1,1)
INSERT INTO #Table2 VALUES(1,2)
I need the result as shown below
C1 C2 C3
--------
1 3 3
2 1 4
This should work:
SELECT Table1.*
FROM Table1
LEFT OUTER JOIN Table2
ON Table1.C1 = Table2.C1
AND Table1.C2 = Table2.C2
WHERE Table2.C1 IS NULL
AND Table2.C2 IS NULL
Please try this -
SELECT t1.*
from table1 t1
where not exists (select null from table2 t2
where t1.c1=t2.c1
and t1.c2=t2.c2);

Join without foreign key for condition

I get two tables like this:
create table #table1 (data1 int)
create table #table2 (data2 int)
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (4),(5),(6)
I want to make a query, that returns two columns like this:
data1 data2
1 4
2 5
3 6
I found one solution for this:
select t1.data1, t2.data2 from
(select row_number() over (order by data1) as [Index], data1 from #table1) as t1 inner join
(select row_number() over (order by data2) as [Index], data2 from #table2) as t2 on (t1.[Index] = t2.[Index])
Do you know other ways to join tables (any joins except cross) without keys?
EDIT: I look for solution without cursor and temporary tables.
create table table1 (data1 int)
create table table2 (data2 int)
insert into table1 (data1) values (1),(2),(3)
insert into table2 (data2) values (4),(5),(6)
create table #table1
(id int identity(1,1),
data1 int)
create table #table2
(id int identity(1,1),
data2 int)
insert into #table1 (data1) select data1 from table1
insert into #table2 (data2) select data2 from table2
create table table3
(data1 int,
data2 int)
insert into table3 (data1, data2)
select #table1.data1, #table2.data2
from #table1
inner join #table2 on #table1.id = #table2.id
what will be output in this case if i insert below values
insert into #table1 (data1) values (1),(2),(3)
insert into #table2 (data2) values (2),(3),(4)
may you need
select t1.data1, t2.data2 from t1,t2