Selecting rows from table1 which do not exists in table2 and inserting it in table2
like
Images
id type name
502 1 summer.gif
SEOImages
id idimage ... ...
1000 501 ... ...
Now I want to select all the rows from Images table whose id does not match idimage SEOImages table and insert those rows into the SEOImages table.
Approach :
Insert into Table2
select A,B,C,....
from Table1
Where Not Exists (select *
from table2
where Your_where_clause)
Example :
SQLFiddelDemo
Create table Images(id int,
type int,
name varchar(20));
Create table SEOImages(id int,
idimage int);
insert into Images values(502,1,'Summer.gif');
insert into Images values(503,1,'Summer.gif');
insert into Images values(504,1,'Summer.gif');
insert into SEOImages values(1000,501);
insert into SEOImages values(1000,502);
insert into SEOImages values(1000,503);
insert into SEOImages
select 1000,id
from Images I
where not exists (select *
from SEOImages
where idimage =I.id);
INSERT INTO SeoImages
(IdImage)
SELECT ID
FROM Images
WHERE ID NOT IN (SELECT IDIMAGE FROM SEOImages)
The query:
SELECT * FROM Images
WHERE id NOT IN (SELECT idimage FROM SEOImages)
should bring out those rows from Images that do not have a corresponding ID in SEOImages, assuming they are both of the same type.
Alternatively, using a JOIN:
SELECT i.* FROM Images i
LEFT OUTER JOIN SEOImages s on i.id = s.imageId
WHERE s.imageId IS NULL
INSERT INTO SEOImages
SELECT *
FROM Images
WHERE NOT EXISTS (SELECT 1
FROM Images t1, SEOImages t2
WHERE t1.id=t2.id) ;
Related
I have a table of products like this:
I want to delete duplicate rows in this table and use the Ids in other tables, so I used a temporary table to add just the Ids to delete and the Ids to keep:
-- create tmp table
create table #tmp (ProductId_ToKeep int, ProductId_ToDelete int);
-- collect the Products that have a lower id with the same name in the temp table
insert into #tmp (ProductId_ToKeep)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] > t1.[ProductId]
);
-- collect the Products that have a higher id with the same name in the temp table
insert into #tmp (ProductId_ToDelete)
select [ProductId]
from dbo.[Product] t1
where exists
(
select 1
from dbo.[Product] t2
where t2.name = t1.name
and t2.[ProductId] < t1.[ProductId]
);
select * from #tmp
After getting what I have in my temp table, I got this result:
I'm asking if any can one help me to put the Ids in each column as I want.
If I followed you correctly, you could use a window function to feed the transcodification table in a single query, like so:
insert into #tmp (ProductId_ToKeep, ProductId_ToDelete)
select *
from (
select
ProductId ProductId_ToDelete,
min(ProductId) over(partition by name) ProductId_ToKeep
from dbo.[Product]
) t
where ProductId_ToDelete != ProductId_ToKeep
The inner query pulls out the smallest ProductId for the given name; the outer query filters on record that should be deleted (ie whose ProductId is not the minimum ProductId for the same name).
I am joining two tables:
DECLARE #Temp TABLE (
id INT)
INSERT INTO #Temp
VALUES (5)
,(2)
,(3)
DECLARE #Temp2 TABLE (
member_id INT)
INSERT INTO #Temp2
VALUES (5)
,(1)
,(3)
How do i count the number of rows that can be LEFT joined and the ones that can't.
In this example: 5 & 3 from #Temp can be joined to #Temp2 and only 2 from #Temp can't be joined.
I would like my output to show the following:
+--------+------------+
| Joined | Not_Joined |
+--------+------------+
| 2 | 1 |
+--------+------------+
You can do this in a single query using COUNT and SUM. This should produce the results you are looking for.
DECLARE #Temp TABLE (
id INT)
INSERT INTO #Temp
VALUES (5)
,(2)
,(3)
DECLARE #Temp2 TABLE (
member_id INT)
INSERT INTO #Temp2
VALUES (5)
,(1)
,(3)
select Joined = count(t2.Member_id)
, NotJoined = sum(case when t2.Member_id is null then 1 end)
from #Temp t
left join #Temp2 t2 on t2.member_id = t.id
The count from #Temp that EXISTS in #Temp2:
SELECT COUNT(*) FROM #TEMP WHERE ID IN(SELECT MEMBER_ID FROM #TEMP2)
The count from #Temp2 not in #Temp:
SELECT COUNT(*) FROM #TEMP2 WHERE MEMBER_ID NOT IN(ID FROM #TEMP)
Now to create a single result set, there are many ways but here is a simple one:
SELECT
(SELECT COUNT(*) FROM #TEMP2 WHERE MEMBER_ID IN(ID FROM #TEMP)) AS [Joined],
(SELECT COUNT(*) FROM #TEMP WHERE ID NOT IN(SELECT MEMBER_ID FROM #TEMP2)) AS [NotJoined]
#Sean Lange's answer is more specific to the JOIN question, my answer simply counts what exists in the lists.
Select count(*) as 'NOT Joined ',
(Select t1.count(*) from table1
t1)-count(*) as 'Joined'
from table1 where id NOT IN (Select member_id from table2);
Its basically how a left join works that is Common values of both the
tables plus the value of table 1 which doesnt exists in table 2.
I am wondering why the below SQL query does not work properly. I am attempting to return the fields from table 1 and table 2 based on the most recent date AND only those elements in those tables that have the name Steve from a third table.
This query, meanwhile, does not actually limit the results to those with the name of Steve. If I remove the second Inner Join and focus on fields only in Table 1 to limit the universe, it works fine.
Appreciate your help on this. I am using Microsft SQL Server Management Studio.
Select *
From [db].table1
INNER JOIN [db].table2 ON table1.id=table2.id
INNER JOIN [db].table3 ON table1.id=table3.id
WHERE (table1.AsOfDate=(SELECT MAX(AsOfDate) from [db].table1))
and table3.Name = 'Steve'
The ID's may not be referring to the same ID across all three tables. Your joins assumes that is the case though. I mirrored your query with sample temp tables and your query works.
--SAMPLE TABLES
IF object_id('tempdb..#table1') is not null drop table #table1
if object_id('tempdb..#table2') is not null drop table #table2
if object_id('tempdb..#table3') is not null drop table #table3
CREATE TABLE #table1 (id INT, my_date date)
INSERT INTO #table1 (id, my_date) VALUES
(1, '1/1/2018'),
(2, '1/2/2018'),
(3, '1/1/2018')
CREATE TABLE #table2 (id INT, some_field VARCHAR(10))
INSERT INTO #table2 (id, some_field) VALUES
(1, 'abc'),
(2, 'xyz'),
(3, 'foo')
CREATE TABLE #table3 (id INT, name VARCHAR(10))
INSERT INTO #table3 (id, name) VALUES
(1, 'jon'),
(2, 'steve'),
(3, 'jane')
--QUERY
SELECT *
FROM #table1 AS x
INNER JOIN
#table2 AS y ON x.id=y.id
INNER JOIN
#table3 AS z ON z.id=x.id
WHERE x.my_date=(SELECT MAX(my_date) from #table1)
and z.name = 'Steve'
output
id my_date id some_field id name
2 2018-01-02 2 xyz 2 steve
I think the simplest way is a window function in the order by:
Select top (1) with ties . . . -- list the columns explicitly
from [db].table1 t1 join
[db].table2 t2
on t1.id = t2.id join
[db].table3 t3
on t1.id = t3.id
where t3.Name = 'Steve'
order by rank() over (order by t1.AsOfDate);
I have two sql temp table #Temp1 and #Temp2, and I want to get rowid which contain set of temp table two
E.g. In table Temp2 have 4 record i want to search in temp table #Temp1 which contain userid departmentid set of record
CREATE TABLE #Temp1(rowid INT, userid INT, departmentid int)
CREATE TABLE #Temp2(userid INT, deparetmentid int)
INSERT INTO #Temp1 (rowid,userid,departmentid )
VALUES (1,1,1),(1,2,2),(1,3,3),(1,4,4),(1,2,1),
(2,2,1),(2,2,2),(2,3,3),(2,4,4),
(3,3,1),(3,2,2),(3,3,3),(3,4,4)
INSERT INTO #Temp2 (userid,departmentid )
VALUES (2,1),(2,2),(3,3),(4,4)
DROP TABLE #Temp1
DROP TABLE #Temp2
i want output rowid 2 because it contain set of (2,1),(2,2),(3,3),(4,4)
one thing in rowid also contain same set of record it its have one more row mean
when i search in temp1 table based on rowid 1 then i found 4 record and when i search rowid 2 then it contain 4 record so that it is same set of record which i found
Thanks
You could use:
SELECT rowid
FROM #Temp1 t1
WHERE NOT EXISTS(SELECT userid, departmentid
FROM #Temp1 tx
WHERE tx.rowid=t1.rowid
EXCEPT
SELECT userid, departmentid
FROM #Temp2)
GROUP BY rowid
HAVING COUNT(*) = (SELECT COUNT(*) FROM #Temp2);
Output:
2
Rextester Demo
Let's assume the rows in table1 are unique. Then you can do this using join and group by:
select t1.rowid
from #table1 t1 left join
#table2 t2
on t1.userid = t2.userid and t1.departmentid = t2.departmentid
group by t1.rowid
having count(*) = (select count(*) from #table2 t2) and
count(*) = count(t2.userid) ;
This assumes no duplicates in either table.
Note: This returns rows that are identical to or a superset of the values in the second table.
Can you please help me out with the below issue?
I have a table like below.
Table-1
Sales_RepID-- Name-- Products_Count
1-- ABC-- 2
2-- XYZ-- 4
3-- XXX-- 3
Table-2
Order_ID-- Sales_RepID-- Products_Count
1001-- 2 -- 2
1002-- 1 -- 1
1003-- 2 -- 1
1004-- 3 -- 3
1005-- 2 -- 2
Table - 1 Result
Sales_RepID, --Name, --Products_Count
1-- ABC --3
2-- XYZ --9
3-- XXX --6
I want to add table-2 Products_Count to Table-1 Products_Count for each Sale_RepID in the table-1
Can you please help with SQL Query?
My database is MS SQL SERVER
For MS SQL Server, please try:
UPDATE T
SET T.Products_Count=T.Products_Count+x.VSum
FROM Table1 T JOIN
(
SELECT DISTINCT
Sales_RepID,
SUM(Products_Count) OVER (PARTITION BY Sales_RepID) VSum
FROM
Table2
)x ON T.Sales_RepID=x.Sales_RepID
create table table1(sales_repId int,name varchar(10),product_count int);
create table table2(order_id int,sales_repId int,product_count int);
insert into table1 values(1,'ABC',2);
insert into table1 values(2,'XYZ',4);
insert into table1 values(3,'XXX',3);
insert into table2 values(1001,2,2);
insert into table2 values(1002,1,1);
insert into table2 values(1003,2,1);
insert into table2 values(1004,3,3);
insert into table2 values(1005,2,2);
select a.sales_repid,name,a.product_count+sum(b.product_count)
from table1 a
inner join table2 b
on a.sales_repid=b.sales_repid
group by a.sales_repid,name,a.product_count
order by a.sales_repid
UPDATE
update table1
set product_count = netProduct
from (
select a.sales_repid,name,a.product_count+sum(b.product_count) as netProduct
from table1 a
inner join table2 b
on a.sales_repid=b.sales_repid
group by a.sales_repid,name,a.product_count
) z
inner join table1 x
on z.sales_repid=x.sales_repid
TRY THIS
DECLARE #TABLE1 AS TABLE( Sales_RepID INT,Name VARCHAR(100), Products_Count int)
DECLARE #TABLE2 AS TABLE( Order_ID INT,Sales_RepID INT, Products_Count int)
INSERT INTO #TABLE1
VALUES(1,'ABC',2),(2,'XYZ',4),(3,'XXX',3)
INSERT INTO #TABLE2
VALUES(1001,2,2),(1002,1,1),(1003,2,1),(1004,3,3),(1005,2,2)
SELECT * FROM #TABLE1
SELECT * FROM #TABLE2
UPDATE T1
SET T1.Products_Count = T1.Products_count + total
FROM #TABLE1 T1
CROSS APPLY (
SELECT total= sum(Products_count)
FROM #Table2 T2
WHERE T1.Sales_RepID =t2.Sales_RepID ) Z
To output as a select:
select
t1.Sales_RepID,
t1.Name,
t1.Products_Count + sum(t2.Products_Count)
from table1 t1
left join table2 t2 on t2.Sales_RepID = t1.Sales_RepID
To update the total in table1, adding the total from table2:
update table1 set
Products_Count = Products_Count + (
select sum(Products_Count)
from table2
where Sales_RepID = table1.Sales_RepID)
These queries will work in all SQL dialects.
MS SQL Server has a special syntax for updating using a join, which will perform much better than the universal update syntax above:
update t1 set
t1.Products_Count = t1.Products_Count + t2.Products_Count
from table1 t1
join (select Sales_RepID, sum(Products_Count) Products_Count
from table2
group by Sales_RepID) t2
on t2.Sales_RepID = t1.Sales_RepID;
See a live demo of this update statement executing on SQLFiddle.
Note that this is an unusual query. Typically, such denormalized values are not cumulative: they are a determinable calculated value, which in this case wold be simply the sum, not the existing value plus the sum. Your design means that the query can only be executed once. After than you'll be repeatedly re-adding the total from table2.
Consider redesigning your tables to have the straight sum from table2 in table1, ie:
update t1 set
t1.Products_Count = t2.Products_Count
from table1 t1
join (select Sales_RepID, sum(Products_Count) Products_Count
from table2
group by Sales_RepID) t2
on t2.Sales_RepID = t1.Sales_RepID;