I want to update one table using another table on field "Id" such that it wont create duplicates
let say my first table is Table1 and second table is Table2 . I would like to update the row in Table1 from Table2 when the Id is matching
I am aware of using UNION function but this applies to entire columns where I only need to consider a single column. https://docs.snowflake.com/en/sql-reference/operators-query.html#union-all
Example of my Tables
Table1
Id name number value
1 a 8 100
2 b 8 100
3 c 8 100
4 d 8 100
Table2
Id name number value
3 c 8 99
4 d 6 100
5 e 7 100
Expected output
Id name number value
1 a 8 100
2 b 8 100
3 c 8 99
4 d 6 100
5 e 7 100
Please note that in the output table row with Id 3,4 has be updated and new Id 5 is inserted.
PS: It would be better if someone could provide me the select statement to get the output table.
The constuct you are searching for is called MERGE:
CREATE OR REPLACE TABLE trg(Id INT, name VARCHAR, number INT, value INT)
AS SELECT 1 ,'a', 8, 100
UNION SELECT 2 ,'b', 8, 100
UNION SELECT 3 ,'c', 8, 100
UNION SELECT 4 ,'d', 8, 100;
CREATE OR REPLACE TABLE src(Id INT, name VARCHAR, number INT, value INT)
AS SELECT 3 ,'c', 8, 99
UNION SELECT 4 ,'d', 6, 100
UNION SELECT 5 ,'e', 7, 100;
Query:
MERGE INTO trg
USING src
ON trg.Id = src.Id
WHEN MATCHED THEN UPDATE SET name = src.name,
number = src.number,
value = src.value
WHEN NOT MATCHED THEN INSERT (ID, name, number, value)
VALUES (src.Id, src.name, src.number, src.value);
SELECT * FROM trg;
Output:
EDIT:
PS: It would be better if someone could provide me the select statement to get the output table.
UNION ALL combined with QUALIFY could be used:
WITH cte AS (
SELECT *, 1 AS priority FROM trg
UNION ALL
SELECT *, 0 AS priority FROM src
)
SELECT Id, Name, Number, Value
FROM cte
QUALIFY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Priority) = 1
ORDER BY Id;
How to select the value from the table based on category_id?
I have a table like this. Please help me.
Table A
ID Name category_id
-------------------
1 A 1
2 A 1
3 B 1
4 C 2
5 C 2
6 D 2
7 E 3
8 E 3
9 F 3
How to get the below mentioned output from table A?
ID Name category_id
--------------------
1 A 1
2 A 1
4 C 2
5 C 2
7 E 3
8 E 3
Give a row number for each row based on group by category_id and sort by ascending order of ID. Then select the rows having row number 1 and 2.
Query
;with cte as (
select [rn] = row_number() over(
partition by [category_id]
order by [ID]
), *
from [your_table_name]
)
select [ID], [Name], [category_id]
from cte
where [rn] < 3;
Kindly run this query It really help You Out.
SELECT tbl.id,tbl.name, tbl.category_id FROM TableA as tbl WHERE
tbl.name IN(SELECT tbl2.name FROM TableA tbl2 GROUP BY tbl2.name HAVING Count(tbl2.name)> 1)
Code select all category_id from TableA which has Name entries more then one. If there is single entry of any name group by category_id then such data will be excluded. In above example questioner want to eliminate those records that have single Name entity like wise category_id 1 has name entries A and B among which A has two entries and B has single entry so he want to eliminate B from result set.
I have one table with 4 columns, say Rec_Id, as int, Name as varchar, ID1 as int, ID2 as int datatypes.
Create table:
Create table Sample
(
Rec_Id Int Not null,
Name varchar(30) null,
ID1 int null,
ID2 int null,
CONSTRAINT [PK_Sample] PRIMARY KEY NONCLUSTERED
(
[Rec_Id] ASC
)
Insert Statement:
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 1 ,'A',1,2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 2 ,'A', 2,3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 3 ,'A', 3 ,1)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 4 ,'B', 1 , 2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 5 , 'B', 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 6 , 'B' , 3 , null)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 7 ,'C', 1 , 2)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 8 ,'C' , 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 9 ,'C' , 3 , 4)
Insert into sample (Rec_ID,Name,ID1,ID2) values (10 ,'C' , 5 , 1 )
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 11 ,'D', 2 , 3)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 12 , 'D', 3 , 4)
Insert into sample (Rec_ID,Name,ID1,ID2) values ( 13 , 'D' , 4 , 3)
My source data looks like this..
Rec_Id Name ID1 ID2
1 A 1 2
2 A 2 3
3 A 3 1
4 B 1 2
5 B 2 3
6 B 3 null --> Need to display this row in the output, because 1 is missing in ID2
7 C 1 2
8 C 2 3
9 C 3 4
10 C 5 1 --> Need to display this row in the output, because 4 is missing after 3 in ID1
11 D 2 3
12 D 3 4
13 D 4 3 --> Need to display this row in the output, because 2 is missing in ID2
My Output should look like below:
Rec_Id Name ID1 ID2
6 B 3
10 C 5 1
13 D 4 3
ok, let me explain in other words...In the above example right now 'Name' column has 4 groups, Name =A, B, C ,D.
A group- has 3 records which make one loop. I am saying it formed one loop becoz 3rd row value in ID2 column(ID2=1) matches with 1st row ID1 column(ID1=1).
Same loop concept implies for B , C and D groups.
--A - group records:
Name ID1 ID2
A 1 2
A 2 3
A 3 1
--B - group records:
Name ID1 ID2
B 1 2
B 2 3
B 3 null
B group - has 3 records which is broken loop. I am saying it is broken loop becoz 3rd row value in ID2 column(ID2=null) doesn't matches with 1st row ID1 column(ID1=1).
C- group records: Same loop concept implies for C group. If there is a break in the series need to display.
D- group records:
Name ID1 ID2
D 2 3
D 3 4
D 4 3
D group - has 3 records which is broken loop. I am saying it is broken loop becoz 3rd row value in ID2 column(ID2=3) doesn't matches with 1st row ID1 column(ID1=2).
So, I need t-sql to get above output.
Thanks in advance,
RH
Here is one way to answer your question. You may want to break it up some depending on your business rules. Based on your sample I could see that the sum of ID1 column equals sum of ID2 column. The rules depend on the first and last values in the ID columns so I figured those out too (used MIN and MAX to get those and add to each row so I could filter at the end).
WITH errs AS (
SELECT s.Rec_id, s.[Name], s.ID1, s.ID2, p.startId, p.lastId, p.TotID1, p.TotID2, 0 AS artificialID
FROM Sample AS s
INNER JOIN (
-- general filter for which groups have problems, assumes sum of ID1 column equals sum of ID2 column (optimize query in case this is bigger data set)
SELECT s0.[Name], SUM(ISNULL(s0.ID1,0)) AS TotID1, SUM(ISNULL(s0.ID2,0)) AS TotID2
, MIN(s0.ID1) AS startId
, MAX(s0.ID1) AS lastId
FROM Sample AS s0
GROUP BY s0.[Name]
HAVING SUM(ISNULL(s0.ID1,0)) <> SUM(ISNULL(s0.ID2,0))) AS p ON s.[Name] = p.[Name]
),
-- get a list of those with a missing row when the last row in the group exists and has the right ID2 value
er1 AS (
SELECT * FROM (
SELECT e.Rec_id, e.[Name], e.ID1, e.ID2, e.startId, e.lastId, e.totID1, e.TotID2, ROW_NUMBER() OVER (PARTITION BY e.[Name] ORDER BY e.ID1) AS artificialID
FROM errs AS e
WHERE e.[Name] NOT IN (SELECT o.[Name] FROM errs AS o WHERE (ISNULL(o.ID1,0) = 0 OR ISNULL(o.ID2,0) = 0))
) AS er1a
WHERE er1a.ID1 <> er1a.artificialID
-- get a list of those where the last row exists and ID2 is correct, IE, something missing in the middle
AND er1a.[Name] IN (SELECT o1.[Name] FROM errs AS o1 WHERE (ISNULL(o1.ID1,0) = lastId AND ISNULL(o1.ID2,0) = o1.startId))
)
SELECT e.*
FROM errs AS e
WHERE (ISNULL(e.ID1,0) = 0 OR ISNULL(e.ID2,0) = 0)
UNION
SELECT e1.*
FROM er1 AS e1
UNION
-- the third group - where the last row does not have the right ID2 on it
SELECT e2.*
FROM errs AS e2
WHERE (ISNULL(e2.ID1,0) = lastId AND ISNULL(e2.ID2,0) <> e2.startId)
ORDER BY [Name],ID1, ID2
The View obtains the first three columns. I need to add one more column (totalCount) to the view that obtains the total count:
CId CCId CCount totalCount
1 a 3 6
1 a 3 6
1 b 3 6
1 c 3 6
2 b 2 6
2 b 2 6
2 a 2 6
2 a 2 6
3 v 1 6
How to get the totalCount as 6?
(Business rule for Cid=1 Ccount=3 Cid=2 Ccount=2 Cid=3 Ccount=1 So the totalCount =3+2+1 =6)
SELECT a.CID, a.CCID, a.CCOUNT,
b.TotalCount
FROM Table1 a, (SELECT SUM(DISTINCT cCOunt) TotalCount
FROM Table1) b
SQLFiddle Demo
UPDATE
As Andomar pointed out on the comment, An update has been made on the query,
SELECT a.CID, a.CCID, a.CCOUNT,
b.TotalCount
FROM Table1 a,
(
SELECT SUM(TotalCount) TotalCount
FROM
(
SELECT MAX(cCOunt) TotalCount
FROM Table1
GROUP BY CId
) c
) b
SQLFiddle Demo
With this code I came to the desired result:
select CId
,CCId
,CCount
,(select SUM(a.tcount)
from (select distinct CId ,CCount as tcount
from dbo.Test) as a ) totalcount
from dbo.Test
From your example data, I'm assuming a Cid can only have one, possibly repeated, value of CCount. In that case you can pick a random one (say max) using a group by, and sum those:
select sum(OneCCCount) as TotalCount
from (
select max(CCount) as OneCCCount
from YourTable
group by
CId
) as SubQueryAlias
I have a table with 10 rows
id values
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
I want to get two rows before and two rows after for #id = 5.
How can get?
Edit This should work as expected (hopefully):
select id, value
from [table]
where id-#id >= -2
AND id-#id <= 2
AND id-#id <> 0
Here's the running sql: http://sqlfiddle.com/#!6/ca4e5/3/0
One possible solution:
select *
from table
where id in (3, 4, 6, 7)
If you are using a int variable #id, you can do it like this:
select *
from table
where id in (#id-2, #id-1, #id+1, #id+2)
To select the previous two:
select top 2 *
from tablename
where id < #id
order by id desc
To select the next two:
select top 2 *
from tablename
where id > #id
order by id asc