i have to check if record exists in table , if there is record then update else insert.
Stg_table
Id seq name company
1 1 aaa yyy
1 2 aaa bbb
table
Id seq name company
1 1 aaa yyy
1 2 aaa bbb
now I have another row in staging with sequence 3
Stg_table
Id seq name company
1 1 aaa yyy
1 2 aaa bbb
1 3 aaa www
I have to check if this exists in table, if it does not exist only then insert. I cannot use MERGE as it is giving me trigger issues and I tried using if exists(below is my code)
If exists(select 1 from stg_table s
join table t
on s.id=t.id and t.seq=s.seq )
begin
update -----
end
else
begin
insert -----
end
How ever, the records are going as updates because it is satisfying the condition. How do i insert in such cases?
table
Id seq name company
1 1 aaa yyy
1 2 aaa bbb
any help is appreciated
Create two separate statements. One that handles the updates and a second that handles the inserts.
Updates:
UPDATE t
SET ....
FROM table t
INNER JOIN stg_table s
ON t.id = s.id
AND t.seq = s.seq
Inserts:
INSERT INTO table (....)
SELECT ..
FROM stg_table s
WHERE NOT EXISTS (
SELECT ...
FROM table t
WHERE t.id = s.id
AND t.seq = s.seq
)
Related
I have one table with 3 columns id,name,new_column So my requirement is to add name column values to new_column but if namae column have duplicate values then in new_column values should be combination of id+name values
Table structure
id name new_name (empty column)
1 aaa
2 bbb
3 ccc
4 ddd
5 aaa
6 eee
7 ccc
Now expected output
id name new_name (empty column)
1 aaa aaa
2 bbb bbb
3 ccc ccc
4 ddd ddd
5 aaa 5aaa (due to duplicate value id + name )
6 eee eee
7 ccc 7ccc (due to duplicate value id + name )
If you want to combine the names in an update, then you can use:
update t join
(select t.*,
row_number() over (partition by name order by id) as seqnum
from t
) tt
on tt.id = t.id
set t.name = concat(t.id, t.name)
where tt.seqnum > 1;
Or without window functions:
update t join
(select name, min(id) as min_id
from t
group by name
) tt
on t.name = tt.name and t.id > tt.min_id
set t.name = concat(t.id, t.name);
If your MySQL version support ROW_NUMBER + window function, you can try to use that make a seq number then use CASE WHEN to judgment whether duplicate
Schema (MySQL v8.0)
CREATE TABLE T(
id int,
name varchar(50)
);
INSERT INTO T VALUES (1,'aaa');
INSERT INTO T VALUES (2,'bbb');
INSERT INTO T VALUES (3,'ccc');
INSERT INTO T VALUES (4,'ddd');
INSERT INTO T VALUES (5,'aaa');
INSERT INTO T VALUES (6,'eee');
INSERT INTO T VALUES (7,'ccc');
Query #1
SELECT name,
CASE WHEN rn = 1 THEN name ELSE CONCAT(id,name) END new_name
FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY name ORDER BY id) rn
FROM T
) t1
ORDER BY id;
name
new_name
aaa
aaa
bbb
bbb
ccc
ccc
ddd
ddd
aaa
5aaa
eee
eee
ccc
7ccc
View on DB Fiddle
I have a MySQL table and it has 2 columns which record users' login info:
User_id Device_id
a 123
b 123
b 321
d 321
e aaa
f ccc
g cba
h aaa
h ccc
i cba
i aaa
Now I want to add a column Group: if user_id are logined by the same group of device, then put them together. For instance, as shown below, user account a and b are logined on device 123, so a and b are in the same group. While user account b is also logined on device 321, then all accounts logined by 321 should join this group
:
User_id Device_id Group
a 123 1
b 123 1
b 321 1
d 321 1
e aaa 2
f ccc 2
g cba 2
h aaa 2
h ccc 2
i cba 2
i aaa 2
This cannot be simply dealed with group by so how to use SQL to express column Group?
You can use the below queries,
// For future insert
INSERT INTO tableName
VALUES (j, '123', CASE grouping
WHEN (SELECT count() FROM tableName tn WHERE tn.Device_id='123')=0 THEN (SELECT MAX(tn.grouping)+1 FROM tableName tn)
WHEN (SELECT count() FROM tableName tn WHERE tn.Device_id='123')>0 THEN (SELECT tn.grouping FROM tableName tn WHERE tn.Device_id='123')
END
);
//Update the existing data
UPDATE tableName
set grouping = CASE grouping
WHEN (SELECT count() FROM tableName tn WHERE tn.Device_id='123')=0 THEN (SELECT MAX(tn.grouping)+1 FROM tableName tn)
WHEN (SELECT count() FROM tableName tn WHERE tn.Device_id='123')>0 THEN (SELECT tn.grouping FROM tableName tn WHERE tn.Device_id='123')
END;
i've a table with records:
----------------------------------
ID | UniqueId | Name | Result
----------------------------------
1 1 Test1 OK
2 1 Test1 Cancelled
3 1 Test1 OK
4 2 Test2 OK
5 2 Test2 OK
6 2 Test2 OK
7 2 Test2 OK
8 3 Test3 OK
9 3 Test3 OK
Let's say i wan't to check if at least one row with UniqueId = 1 not contains Result == Cancelled. To exclude record with UniqueId = 1, because it is cancelled.
How can i do this?
Thank you
SELECT t1.* from table as t1 where t1.UniqueId not in(select t.UniqueId from table as t
where t.Result="Cancelled")
Just ask for rows with UniqueId = 1 and Result != Cancelled
SELECT ID FROM table WHERE UniqueId = 1 AND Result <> 'Cancelled' LIMIT 1
I'd go this way, but the other answers are a bit easier in terms of syntax.
SELECT UniqueId, Name
FROM Table T
GROUP BY UniqueId, Name
HAVING Result != 'Cancelled'
SELECT id FROM mytable WHERE uniqueId = 1 AND result != 'Cancelled'
I'm using the SQL Server 2008.
Now I have the scenario as description below:
1 table with 3 columns: ID, Name, Order.
They has 8 records.
5 records have the same data: ID='1', Name='AAA'
3 records have the same data: ID='2', Name='BBB'
Now I want to update Order column with number increasing (start from 1) for each ID,Name:
No Name Order
1 AAA 1
1 AAA 2
1 AAA 3
1 AAA 4
1 AAA 5
2 BBB 1
2 BBB 2
2 BBB 3
How can I get this result without using Cursors?
I'm very appriciated for your help.
Thanks.
You can try the following. I use CTE to drive the update statement
WITH data AS
(
SELECT Order
, ROW_NUMBER() OVER (PARTITION BY ID, NAME
ORDER BY ID, NAME) AS Seq
FROM TableA
)
UPDATE data
SET Order = Seq
Substitute TableA with your table name
I have a table such as:
id name ref_id order data_obj
-- ---- ------ ----- --------
1 Sam 0 15 [binary data]
2 Jack 0 20 [binary data]
3 Sue 0 25 [binary data]
4 Sam2 1 - [no data]
5 Sue2 3 - [no data]
6 Sam3 1 - [no data]
The idea is that I have more columns other than data_obj which can be common, so I don't want to insert them again, just want to insert a reference id to the same data.
Is it possible to write a query and select this:
1 - Sam - binary data from id 1
4 - Sam2 - binary data from id 1
6 - Sam3 - binary data from id 1
2 - Jack - binary data from id 2
3 - Sue - binary data from id 3
5 - Sue2 - binary data from id 3
Please note that I'm ordering according to column named order and there's no actual data for this column for referenced rows.
SELECT t1.id, t1.name, t2.data_obj
FROM your_table t1
LEFT JOIN your_table t2 ON t1.ref_id = t2.id
ORDER BY t1.order
Other version, which doesn't return rows without ref
SELECT t1.id, t1.name, t2.data_obj
FROM your_table t1, your_table t2
WHERE t1.ref_id = t2.id
ORDER BY t1.order
Here's a modification of #vartec's answer. This modification uses COALESCE() to combine the data_obj from either the primary row or the referenced row.
SELECT t1.id, t1.name, COALESCE(t1.data_obj, t2.data_obj)
FROM your_table t1
LEFT JOIN your_table t2 ON t1.ref_id = t2.id
ORDER BY COALESCE(t1.order, t2.order), ref_id;
COALESCE() is a standard SQL function that returns its first non-NULL argument.
Why aren't you using more than one table?
CREATE TABLE user (
user_id number not null (some form of auto increment or sequence),
name varchar(50) not null,
otherdata type,
primary key (id));
CREATE TABLE common (
common_id number not null (autoinc),
user_id number not null,
commondata type,
primary key (common_id),
unique index (user_id, common_id));
SELECT u.name, u.otherdata, c.commondata
FROM user u, common c
WHERE u.user_id = c.user_id
TABLE user
user_id name otherdata
1 Sam abc
2 Jack def
3 Sue ghi
Table common
common_id user_id commondata
1 1 AAA
2 1 BBB
3 1 CCC
4 2 DDD
5 3 EEE
6 3 FFF
Output
name otherdata commondata
Sam abc AAA
Sam abc BBB
Sam abc CCC
Jack def DDD
Sue ghi EEE
Sue ghi FFF