Update Value from Reference table - sql

I'm Working with Sql server 2008 i have two tables and one reference table.table1 contains ,
Id Name test1 test2
1 sss started processing
2 asdfasd started processing
table 2 contains,
Id Name test1 test2
1 sss 2 2
2 asdfasd 3 2
reference table has ,
code Name
1 Started
2 processing
3 stopped
i have to write update query to change the table 2 values as following,
Id Name test1 test2
1 sss 1 2
2 asdfasd 1 2
how to write update query for the above scenario?

Please find example below.
You can do this in one UPDATE
DECLARE #table1 Table (ID INT, NAME VARCHAR(100), test1 VARCHAR(100), test2 VARCHAR(100))
INSERT INTO #table1 SELECT 1, 'sss', 'started', 'processing'
INSERT INTO #table1 SELECT 2, 'asdfasd', 'started', 'processing'
DECLARE #table2 Table (ID INT, NAME VARCHAR(100), test1 INT, test2 INT)
INSERT INTO #table2 SELECT 1, 'sss', 2, 2
INSERT INTO #table2 SELECT 2, 'asdfasd', 3, 2
DECLARE #refTable Table (CODE INT, NAME VARCHAR(100))
INSERT INTO #refTable SELECT 1, 'Started'
INSERT INTO #refTable SELECT 2, 'processing'
INSERT INTO #refTable SELECT 3, 'stopped'
UPDATE T2
SET test1 = R1.Code,
test2 = R2.Code
FROM #table2 T2
INNER JOIN #table1 T1
ON T1.ID = T2.ID
INNER JOIN #refTable R1
ON T1.test1 = R1.Name
INNER JOIN #refTable R2
ON T1.test2 = R2.Name
SELECT *
FROM #table2

Related

Get exact match between two table

I have a issue that is hard to explain. I have two tables
table1: (this is something like shipping table)
ID ShippingId ProductId1 ProductId2
1 100 A A1
2 100 A A2
3 100 A A3
4 100 A A4
5 100 A A5
6 200 B B1
7 200 B B2
8 300 B A1
9 300 B A2
table2: (and this is about relation between ProductId1 and ProductId2)
ID ProductId1 ProductId2
1 A A1
2 A A2
3 A A3
4 A A4
5 A A5
6 B B1
7 B B2
In the case the shipment "100" includes all items of "A" so this should "true"
and the shipments "200" and "300" does not include all parts of their main products. So expected output should be like
ShippingId ProductId1 IsIncludeAll
100 A true
200 B false
300 A true
can you guys help me?
DECLARE #table1 AS TABLE
(
ShippingID INT,
ProductId1 INT,
ProductId2 INT
)
DECLARE #table2 AS TABLE
(
ProductId1 INT,
ProductId2 INT
)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1119)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1118)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1117)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1116)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (100,111, 1115)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (200,222, 2229)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (200,222, 2228)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (300,111, 1117)
INSERT INTO #table1 (ShippingId,ProductId1,ProductId2) VALUES (300,111, 1116)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 111, 1119)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 111, 1118)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 111, 1117)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 111, 1116)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 111, 1115)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 222, 2229)
INSERT INTO #table2 (ProductId1,ProductId2) VALUES ( 222, 2228)
ShippingId ProductId1 IsIncludeAll
100 A true
200 B false
300 A false
A total guess, as the sample DDL and DML don't match the sample data, but perhaps this?
SELECT S.ShippingID,
T2.ProductId1,
CASE COUNT(CASE WHEN T1.ProductId2 IS NULL THEN 1 END) WHEN 0 THEN 'true' ELSE 'false' END AS IsIncludeAll
FROM #table2 T2
CROSS APPLY (SELECT DISTINCT
sq.ShippingID,
sq.ProductId1
FROM #table1 sq
WHERE sq.ProductId1 = T2.ProductId1) S
LEFT JOIN #table1 T1 ON T2.ProductId1 = T2.ProductId1
AND T1.ProductId2 = T2.ProductId2
AND S.ShippingID = T1.ShippingID
GROUP BY S.ShippingID,
T2.ProductId1;
Little confused on your sample data and output. From my thought Check this query and output.
------Step 1. concatenate product1 and product2 with ShippingID wise,product1 wise order by ShippingID,ProductId1,ProductId2-------------------
declare #Shipping as table
(
ShippingID INT,
ProductId1 INT,
ProductDesc varchar(max)
)
insert #Shipping
SELECT Shipping.ShippingID,Shipping.ProductId1,
LEFT(Shipping.prod_desc,Len(Shipping.prod_desc)-1) As prod_desc
FROM
(
SELECT DISTINCT T2.ShippingID, T2.ProductId1,
(
SELECT cast(T1.ProductId1 as varchar(10))+'-' +cast(T1.ProductId2 as varchar(10))+ '|' AS [text()]
FROM dbo.table1 T1
WHERE T1.ShippingID = T2.ShippingID and T1.ProductId1=T2.ProductId1
ORDER BY T1.ShippingID,ProductId1,ProductId2
FOR XML PATH ('')
) prod_desc
FROM dbo.table1 T2
) Shipping
------Step 2. concatenate product1 and product2 with product1 wise order by ProductId1,ProductId2-------------------
declare #relation as table
(
ProductId1 INT,
ProductDesc varchar(max)
)
insert #relation
SELECT relation.ProductId1,LEFT(relation.prod_desc,Len(relation.prod_desc)-1) As prod_desc
FROM
(
SELECT DISTINCT T2.ProductId1,
(
SELECT cast(T1.ProductId1 as varchar(10))+'-' +cast(T1.ProductId2 as varchar(10))+ '|' AS [text()]
FROM dbo.table2 T1
WHERE T1.ProductId1=T2.ProductId1
ORDER BY ProductId1,ProductId2
FOR XML PATH ('')
) prod_desc
FROM dbo.table2 T2
) relation
------Step 1. use left join to match with concatinated string of every product1. if matches return True otherwise False-------------------
select a.ShippingID,a.ProductId1,case when b.ProductDesc is null then 'False' else 'True' end as IsIncludeAll
from #Shipping a
left join #relation b
on a.ProductId1=b.ProductId1 and a.ProductDesc=b.ProductDesc
-----Result-----------
------------+---------------+--------------
ShippingID | ProductId1 | IsIncludeAll
------------+---------------+--------------
100 | 111 | True
200 | 222 | True
300 | 111 | False

I would like to update table using merge and my table source will use cross join

I have a Table1:
IdT1 : 11, 12, 13
IdT1Group : 30,30,30
Table2:
IdT2 : 1, 2, 3, 4
IdT1 : 11, 11, 12, 12
Detail : A, B, A, B
AND User Defined Table Type #T2:
IdT2 : 1, 2, 3
IdT1 : 11,11,11
Detail: A,B,C
I would like to Update Table2 to be:
IdT2 : 1,2,5, 3,4,6, 7,8,9
IdT1 : 11,11,11, 12,12,12, 13,13,13
Detail : A,B,C, A,B,C, A,B,C
So, I was Use Merge in StoredProcedure:
;WITH Table2
AS (SELECT Table2.* FROM Table2 INNER JOIN Table1 ON Table2.IdT1 = Table1.IdT1 AND IdT1Group = 30)
MERGE INTO Table2 AS tblTarget
USING (SELECT #T2.*, T1Item.IdT1 AS T1Id FROM #T2 CROSS JOIN Table1 where IdT1Group = 30)
AS tblSource
ON tblTarget.IdT1 = tblSource.T1Id And tblTarget.IdT2 = tblSource.IdT2
WHEN MATCHED THEN
UPDATE
SET Detail = tblSource.Detail
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN NOT MATCHED BY TARGET THEN
INSERT (IdItem, IdT2, Detail)
VALUES (tblSource.IdT1,
tblSource.IdT2, tblSource.Detail);
But after i tried my code, my table2 become:
IdT2 : 1,2,5, 6,7,8, 9,10,11
IdT1 : 11,11,11, 12,12,12, 13,13,13
Detail: A,B,C, A,B,C, A,B,C
This is what should it be:
IdT2 : 1,2,5, 3,4,6, 7,8,9
IdT1 : 11,11,11, 12,12,12, 13,13,13
Detail : A,B,C, A,B,C, A,B,C
I think the output should look like follows because one of the values get deleted. further i think you have a identity column or a incremental value in the Table2 for IdT2.
when you delete an item the increased value will not get deducted.
output
IdT2 IdT1 Detail
----------- ----------- -------
1 11 A
2 11 B
5 11 C
3 12 C
6 12 A
7 12 B
8 13 A
9 13 B
10 13 C
SQL statement (NOTE: Created # tables instead of physical tables to get this going)
create table #Table1
(
IdT1 int , IdT1Group int
)
insert into #Table1
select 11 IdT1,30 IdT1Group union all
select 12 IdT1,30 IdT1Group union all
select 13 IdT1,30 IdT1Group
create table #Table2
(
IdT2 int identity(1,1), IdT1 int , Detail varchar(100)
)
insert into #Table2
SELECT 11 IdT1 ,'A' Detail union all
SELECT 11 ,'B' union all
SELECT 12 ,'A' union all
SELECT 12 ,'B'
declare #T2 table
(
IdT2 int , IdT1 int , Detail varchar(100)
)
insert into #T2
SELECT 1 IdT2 , 11 IdT1 ,'A' Detail union all
SELECT 2 , 11 ,'B' union all
SELECT 3 , 12 ,'C'
MERGE INTO #Table2 AS tblTarget
USING (SELECT T2.*, T1Item.IdT1 AS T1Id FROM #T2 T2 CROSS JOIN #Table1 T1Item where IdT1Group = 30)
AS tblSource
ON tblTarget.IdT1 = tblSource.T1Id And tblTarget.IdT2 = tblSource.IdT2--tblTarget.IdT1 = tblSource.T1Id And tblTarget.IdT2 = tblSource.IdT2
WHEN MATCHED THEN
UPDATE
SET Detail = tblSource.Detail
WHEN NOT MATCHED BY SOURCE THEN
DELETE
WHEN NOT MATCHED BY TARGET THEN
INSERT (IdT1, Detail)
VALUES (tblSource.T1Id,
tblSource.Detail);
select * from #Table2
order by 2,1
drop table #Table1
drop table #Table2

Get records from a table that hit all detail types in another table

I have two tables, Table1 contains master records and Table2 contains details.
How I can get all records in Table1 that hit all details in Table2
CREATE Table1 ([ID] INT , [Title] VARCHAR(256))
CREATE Table2 ([ID] INT, [Table1_ID] INT, [Detail] INT)
Sample:
Table1:
ID Title
---------------
1 Data_1
2 Data_2
3 Data_3
Table2
ID Table1_ID Detail
-------------------------------
1 1 500
2 1 600
3 2 500
4 3 500
5 3 600
I need to this result:
Result:
Table1_ID Table1_Title
----------------------
1 Data_1
3 Data_3
I'm looking for a way with best performance.
This is basic inner join example:
select Table1.ID, Title
from Table1
inner join Table2 on Table1.ID = Table2.Table1_ID
An INNER JOIN between the two tables will get you the results that exist in both tables, so :
SELECT
T1.ID, T1.Title
FROM Table1 T1
INNER JOIN Table2 T2 ON T1.ID = T2.Table1_ID
Would get you all the records from the tables were the ID from Table1 is in Table2
There's a splendid post HERE which explains the different types of joins
Here you go:
DECLARE #T1 TABLE (ID INT, Title VARCHAR(256));
DECLARE #T2 TABLE (ID INT, Table1_ID INT, Detail INT);
INSERT INTO #T1 VALUES
(1,'Data_1'),
(2,'Data_2'),
(3,'Data_3');
INSERT INTO #T2 VALUES
(1,1,500),
(2,1,600),
(3,2,500),
(4,3,500),
(6,3,600);
SELECT T1.ID Table1_ID, T1.Title Table1_Title
FROM #T1 T1 INNER JOIN #T2 T2 ON T1.ID = T2.ID
WHERE T1.ID IN (1,3);
Output:
+-----------+--------------+
| Table1_ID | Table1_Title |
+-----------+--------------+
| 1 | Data_1 |
| 3 | Data_3 |
+-----------+--------------+
Demo.
I found this solution I am not sure if it is the best way to do this?
DECLARE #T1 TABLE ([ID] INT, [Title] VARCHAR(256));
DECLARE #T2 TABLE ([ID] INT, [Table1_ID] INT, [Detail] INT);
INSERT INTO #T1
VALUES
(1, 'Data_1'),
(2, 'Data_2'),
(3, 'Data_3');
INSERT INTO #T2
VALUES
(1, 1, 500),
(2, 1, 600),
(3, 2, 500),
(4, 3, 500),
(5, 3, 600);
DECLARE #DetailCount INT
SELECT #DetailCount = COUNT(DISTINCT [Detail]) FROM #T2
SELECT
T1.[ID] [Table1_ID],
T1.[Title] [Table1_Title]
FROM
#T1 T1 INNER JOIN
#T2 T2 ON T1.[ID] = T2.[Table1_ID]
GROUP BY
T1.[ID],
T1.[Title]
HAVING
COUNT(T2.[Detail]) = #DetailCount

Adding multiple columns of multiple tables into one column

I have two tables with same column name I have to add the oprId column values for some specific condition on both tables.
Table 1
something oprId
abc 1
qwe 2
Table 2
something oprId
abc 2
qwe 5
Result should be
oprId
3
7
declare #T1 table (something varchar(3), oprId int)
declare #T2 table (something varchar(3), oprId int)
insert into #T1 values ('abc', 1),('qwe', 2)
insert into #T2 values ('abc', 2),('qwe', 5)
select T1.oprId+T2.oprId as oprId
from #T1 as T1
inner join #T2 as T2
on T1.something = T2.something
Result:
oprId
------
3
7
SELECT ISNULL(A.something,B.something) Something,
ISNULL(A.oprId,0)ÍSNULL(B.oprId,0) oprId
FROM Table1 A
FULL JOIN Table2 B
ON A.something = B.something

SQL Management Studio Selecting specific children

So I have three tables, table1, table2, and table3. They each have ID fields, table1ID, table2ID, and table3ID respectively. Additionally, table2 has a field table1ID which points to a row in table1, and table3 has a field table2ID which points to a row in table2.
So, my question is, how do I do a select statement that selects only the rows in table3 that reference a row in table2 that reference a row in table1 with the ID 4?
You're looking at a link of joins similar to this
select * from table3
join table2 on table3.table2ID = table2.table2ID
join table1 on table2.table1ID = table1.table1ID
where table1.ID = 4
this will only return table3 records if there is a matching table2 AND table 1 record. The join will filter the results out where the joins match, and the WHERE filter will only select from the results where table1 ID = 4.
A working sample I whipped up (hey I have time to kill)
create table #table1 (table1ID int)
create table #table2 (table2ID int, table1ID int)
create table #table3 (table3ID int, table2ID int)
insert into #table1 values(1)
insert into #table1 values(2)
insert into #table1 values(3)
insert into #table1 values(4)
insert into #table2 values(10, 1)
insert into #table2 values(11, 2)
insert into #table2 values(12, 3)
insert into #table2 values(13, 4)
insert into #table3 values(20, 10)
insert into #table3 values(21, 11)
insert into #table3 values(22, 12)
insert into #table3 values(23, 13)
-- all joined records
select * from #table3
join #table2 on #table3.table2ID = #table2.table2ID
join #table1 on #table2.table1ID = #table1.table1ID
-- only where table1 ID = 4
select * from #table3
join #table2 on #table3.table2ID = #table2.table2ID
join #table1 on #table2.table1ID = #table1.table1ID
where #table1.table1ID = 4
drop table #table1
drop table #table2
drop table #table3
This gives you
table3ID table2ID table2ID table1ID table1ID
----------- ----------- ----------- ----------- -----------
20 10 10 1 1
21 11 11 2 2
22 12 12 3 3
23 13 13 4 4
table3ID table2ID table2ID table1ID table1ID
----------- ----------- ----------- ----------- -----------
23 13 13 4 4