Insert data into two columns only if not duplicate - sql

I have a table user_interests with id(AUTO_INC), user_id, user_interest columns.
I want a easy way to insert data into user_id and user_interest without duplicate entries.
E.g. if I have a table like this before.
+------------------------------+
| ID | user_id | user_interest |
+------------------------------+
| 1 | 2 | Music |
| 2 | 2 | Swimming |
+------------------------------+
If I now insert into table (user_id, user_interest) values ((2, Dance),(2, Swimming), I only need (2,dance) entry to be inserted - not (2, swimming) since (2, swimming) already exists in the table.
I have seen upsert commands, and have also tried creating a command like below but it doesn't work.
INSERT INTO `user_interests`( `user_id`,`interest` )
VALUES ("2","Music")
WHERE (SELECT COUNT(`interest`) FROM `user_interests`
WHERE `interest` = "Music" AND `user_id` = "2"
Having COUNT(`interest`) <=0 )

Use NOT EXISTS method :
INSERT INTO your_table (user_id ,user_interest )
SELECT #userId , #UserIntreset
WHERE NOT EXISTS(SELECT 1 FROM your_table user_id = #userid AND user_interest
= #userinterest )
Or Create unique constraint in your table,
ALTER TABLE your_table
ADD CONSTRAINT Constraint_Name UNIQUE (Column_Name1,Column_Name2)

Related

Insert value of one column from one table to another table based on where condition

I have one question . Suppose there is one table rules in which column department, action ,left_source and right_source,left_source_id,right_source_id is there .Another table is source table where column is name,I'd .
Now i have to insert rules to rule table but in left_source_id and right_source_id i have to insert value from source table based on I'd column . I need some immediate help .
(Source table column I'd contains all the name of left_source and right_source )
Insert Select...union all..select for example
drop table if exists t,t1;
create table t(id int,leftsource varchar(1),rightsource varchar(1));
create table t1(id int,val varchar(1));
insert into t1 values
(1,'l'),(2,'r');
insert into t
select id,val,null from t1 where id = 1
union all
select id,null,val from t1 where id = 2
select * from t;
+------+------------+-------------+
| id | leftsource | rightsource |
+------+------------+-------------+
| 1 | l | NULL |
| 2 | NULL | r |
+------+------------+-------------+
2 rows in set (0.001 sec)

How to update multiple SQL records with same condition

I have this table
id | attributeId | value
--------------------------
1 | 1 | abc
2 | 1 | def
I want to update this table where "attributeId = 1" with these values {"123", "456", "789"} so the table will look like this:
id | attributeId | value
--------------------------
1 | 1 | 123
2 | 1 | 456
3 | 1 | 789
My idea is to delete all the old records and then add new records but I think there are more better method to do this. Is there any better way?
Consider following:
Alter table Your_Table DROP COLUMN VALUE
CREATE TABLE TEMP (ID INT, VALUE VARCHAR(3));
INSERT INTO TMP VALUES (1, '123'), (1, '456'), (1, '789');
SELECT A.*, B.VALUE INTO NEW_TABLE FROM Your_Table a join TMP b on a.id = b.id;
The new_table will have your requested structure.
If your goal is to replace the table, then just delete all the rows and insert new values:
truncate table t;
insert into t (id, attributeId, value)
values (1, 1, 123),
(2, 1, 456),
(3, 1, 789);
If you don't want the original rows that are not in the new data, I would not bother trying to figure out the differences between the tables. The truncate should be pretty fast and bulk updates are usually faster than update some records and insert some others.

POSTGRESQL - Find a row with a specific set of join table data

I have Users in Groups. I am trying to find which Group contains ONLY a specific set of Users. For instance Bob is in the group [Bob + John], but also in the group [Bob + John + Steve], and I would like to match the first one.
I use a join table groups_users to link Users to Groups.
I am having a hard time coming up with a query that will use the join table to match the users to the group, but also using that join table to exclude groups (groups that do not have the exact set of user searched).
Here is a fiddle with some data.
Schema (PostgreSQL v13 (Beta))
CREATE TABLE users (
id SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
username VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE groups (
id SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE groups_users (
group_id INT NOT NULL,
user_id INT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT fk_group
FOREIGN KEY(group_id)
REFERENCES groups(id),
CONSTRAINT fk_user
FOREIGN KEY(user_id)
REFERENCES users(id)
);
INSERT INTO users (username)
VALUES ('bob'), ('john'), ('steve');
INSERT INTO groups DEFAULT VALUES;
INSERT INTO groups DEFAULT VALUES;
INSERT INTO groups DEFAULT VALUES;
INSERT INTO groups_users (group_id, user_id)
VALUES (1, 1),
(1, 2),
(2, 2),
(2, 3),
(3, 1),
(3, 2),
(3, 3);
Query #1
SELECT * FROM groups_users
WHERE groups_users.user_id IN (1, 2);
| group_id | user_id | created_at |
| -------- | ------- | ------------------------ |
| 1 | 1 | 2020-11-22T16:12:35.796Z |
| 1 | 2 | 2020-11-22T16:12:35.796Z |
| 2 | 2 | 2020-11-22T16:12:35.796Z |
| 3 | 1 | 2020-11-22T16:12:35.796Z |
| 3 | 2 | 2020-11-22T16:12:35.796Z |
We see that we match groups 1, 2 and 3, but we only want to match 1, and I don't know how to go about querying this.
Thank you for your help.
You can group your groups and aggregate the user_ids into arrays. Than can compare these aggregations with created user_id arrays:
demo:db<>fiddle
SELECT
group_id
FROM
groups_users
GROUP BY group_id
HAVING ARRAY_AGG(user_id) = ARRAY[1,2]
This is gross and I apologize, but what this query does is gets a count of the row results for groups with your filter applied and then compares it to the total members of the group and only includes groups which only include those members.
SELECT t1.group_id FROM
(
SELECT group_id, COUNT(group_id) AS Instances FROM groups_users
WHERE groups_users.user_id IN (1, 2)
GROUP BY group_id
) T1
INNER JOIN
(
SELECT group_id, COUNT(group_id) AS Instances FROM groups_users
GROUP BY group_id
) T2
ON T1.group_id = T2.group_id and t1.Instances = t2.Instances

how to avoid duplicate entries in hive?

Create a table with primary key in Hive.
Insert the identical data record several times.
How can you avoid that the data record (primary key) is not inserted more than once without using a second temporary table?
drop table t1;
CREATE TABLE IF NOT EXISTS `t1` (
`ID` BIGINT DEFAULT SURROGATE_KEY(),
`Name` STRING NOT NULL DISABLE NOVALIDATE,
CONSTRAINT `PK_t1` PRIMARY KEY (`ID`) DISABLE NOVALIDATE);
select * from t1;
+--------+----------+
| t1.id | t1.name |
+--------+----------+
+--------+----------+
insert into t1 values (1, "Hi");
insert into t1 values (1, "Hi");
insert into t1 values (1, "Hi");
select * from t1;
+--------+----------+
| t1.id | t1.name |
+--------+----------+
| 1 | Hi |
| 1 | Hi |
| 1 | Hi |
+--------+----------+
I tried unsuccessfully with a merge:
MERGE INTO t1
USING (select * from t1) sub
ON sub.id != t1.id
WHEN not matched then insert values (2, "World");

Insert -> select and add my column

how i can added my values in column
for example
t1
id | name | surname | mycolumn
1 | f | g |
+++|++++++|+++++++++|++++++++++
and t2
u_id | u_name | u_surname
1 | 2f | 2g
+++++|++++++++|+++++++++++
:)
so, query
INSERT INTO t1 SELECT (u_name,u_surname) FROM t2 WHERE u_id = 1
how set value mycolumn, in my variable?
If I understood your question: you are trying to insert values into a table from another table but they have different column names and different column count. In that case, you can simply rename the columns of the second table since you are querying the result, but you will need a third column, for that use NULL if you don't have a value yet
INSERT INTO t1
SELECT u_id id,u_name name,u_surname surname, null mycolumn
FROM t2 WHERE u_id = 1