SQL: INSERT INTO table(...) VALUES (...) with data retrieved from other tables - mysql

Thank you for passing by. I know basic SQL syntax and I can't seem to find a way to accomplish this task.
I need to create a stored procedure which inserts data from one table in another, amid retrieving data from many others. Suppose I have these tables with columns:
users
name (varchar)
sub_id (int)
dub_id (int)
tmp_users
name (varchar)
sub_name (varchar)
dub_name (varchar)
subs
id (int)
name (varchar)
dubs
id (int)
name (varchar)
Translated in pseudocode I should do something like this:
INSERT INTO users (name, sub_id, dub_id)
ALL ROWS FROM tmp_users VALUES (
name = tmp_users.name,
sub_id = SELECT id FROM subs WHERE tmp_users.sub_name = subs.name,
dub_id = SELECT id FROM dubs WHERE tmp_users.dub_name = dubs.name,
)
In wording I need to insert into users all rows from tmp_users, to keep the col tmp_users.name, but retrieve the afferent ids of all other tables based on *_name column. How should I approach this task?

It seems like you are looking for the INSERT ... SELECT syntax:
INSERT INTO users (name, sub_id, dub_id)
SELECT
tu.name,
s.id,
d.id
FROM tmp_users tu
LEFT JOIN subs s ON s.name = tu.sub_name
LEFT JOIN dubs d ON d.name = tu.dub_name
This brings all rows from tmp_users, then attempt to recover the corresponding sub_id and dub_id. For each row returned by the select, a record is inserted in users. A good thing about this syntax is that you can run the select query independently first, to see what would be inserted.

Related

How to find duplicate fields using SQL?

I have table person(id, iin, name, done) and table err_person(id, iin, surname, name). How i can find duplicate values within 'iin' fields. If it exist, copy to err_person table and set flag person.done=1 for these rows.
person table
desired results: err_person
To find duplicate values in a field:
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1
You may wish to nest this query:
SELECT * FROM person WHERE iin IN (
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1)
And so, to insert this into the err_person table you could do something like this (noting that the person table does not have a surname field):
INSERT INTO err_person (id, iin, name)
SELECT id, iin, name FROM person WHERE iin IN (
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1)
Finally, a separate query would have to be run to change the done field. The problem with a nested query here is that you're updating a table that you're trying to look at, thus a simple effort to use an update query that looks at a subquery will fail - because both are based on the person table. A temporary table might be a better option here.

Select rows from a table not matched in another table

So I have the following:
A lookup table that has two columns and looks like this for example:
userid moduleid
4 4
I also have a users table that has a primary key userid which the lookup table references. The user table has a few users lets say, and looks like this:
userid
1
2
3
4
In this example, it show that the user with ID 4 has a match with module ID 4. The others are not matched to any moduleid.
I need a query that gets me data from the users table WHERE the moduleid is not 4. In my application, I know the module but I don't know the user. So the query should return the other userids apart from 4, because 4 is already matched with module ID 4.
Is this possible to do?
I think I understand your question correctly. You can use a sub-query to cross-check the data between both tables using the NOT IN() function.
The following will select all userid records from the user_tbl table that do not exist in the lookup_tbl table:
SELECT `userid`
FROM `user_tbl`
WHERE `userid` NOT IN (
SELECT DISTINCT(`userid`) FROM `lookup_tbl` WHERE moduleid = 4
)
There are several ways to do this, one pretty intuitive way (in my opinion) is the use an in predicate to exclude the users with moduleid 4 in the lookup table:
SELECT * FROM Users WHERE UserID NOT IN (SELECT UserID FROM Lookup WHERE ModuleID = 4)
There are other ways, with possibly better performance (using a correlated not exists query or a join for instance).
One other option is to use a LEFT JOIN so that you can get the values from both tables, even when there is not a match. Then, pick the rows where there is no userid value from the lookup table.
SELECT u.userid
FROM usersTable u
LEFT JOIN lookupTable lt ON u.userid = lt.userid
WHERE lt.userid IS NULL
Are you looking for a query like this?
select userid from yourtablename where moduleid<>4

Differences between two result sets MySQL

Very beginner question but haven't been able to come up with answer after reading various help resources.
I have a table group_affiliations which is a joining table between the tables users and groups. Relevant columns: Id, user_id, group_id. I am doing a data cleanup where users were assigned a group_id based on a location which used to be a 3 character abbreviation of a city but has since gone to spelling out full city (ex: a group_id for CHA was previously assigned and now a group_id for Charlotte). Most users currently have both group_ids associated with their user_id but some still only have the old group_id and were never assigned the new one.
What is the most efficient way of finding which ids are in this result set:
select user_id from group_affiliations where group_id=OldId;
and not in this result set:
select user_id from group_affiliations where group_id=NewId;
SELECT 'user_id'
from 'group_affiliations'
where 'group_id' = OldId
and 'group_id' != NewId
how about using a JOIN
SELECT g1.'user_id'
from 'group_affiliations' g1
inner join 'group_affiliations' g2
on g2.'group_id' != NewId
and g2.'group_id' = OldId
and g1.'user_id'=g2.'user_id'

mysql insert information from multiple rows from another table

I am using MySQL version 5.6.
I have a table event that takes two ids and a date, and a table student that contains a column id. I want to insert two ids when the name match (WHERE firstname =.., AND lastname=..,). However, I don't quite know how to take id from two rows in one insert command. Can any one help me please?
Thanks,
Paul
If you are trying to insert into a table, then you want to use insert. To get data from another table or query, you would want the insert . . . select form.
From what you say, this seems something like what you want:
insert into event(id1, id2, date)
select s1.id, s2.id, now()
from student s1 cross join
student s2
where s1.id <> s2.id and
s1.firstname = firstname and s1.lastname = lastname and
s2.firstname = firstname and s2.lastname = lastname;
It would return all pairs of students where the names match (but don't have the same id).

reading data from three tables using mysql

I have to join the data from two tables.
There are three table record,address and names.Id is the primary key in record table and foreign key in address and names table.There can be multiple name records for particular record.
RECORD(id (PK),text,search)
address(address_id(PK),type,street,city, id (FK))
name(name_id(PK),name,id (FK))
I want to get the data from these three tables in a way so that i will get the only first name record for each record id,not all the name records for record id's.
insert into RECORD values (1,record1,record1search);
insert into RECORD values (2,record2,record2search);
insert into name values (1,xxx,1);
insert into name values name(2,yyy,1)
insert into name values name(3,zzz,2)
i want to retriev the values in way:
record_id,text,namename_id:
1,record1,xxx,1
2,record2,zzz,3
I want the only first name record not the second or thirrd name record for particular record.
please help.
You will need an interim query on name by the record ID to find the FIRST ID and use THAT as basis to join to the actual name table. Also, you didn't provide any sample data for your address table, but that would be done in a similar fashion as the first names query performed here. Also, would the address table be associated to a specific named person and not just the ID? Will THAT be 1:many relationship to the Record ID?
select
r.id,
r.text,
n2.name,
n2.name_id
from
Record r,
join ( select n.id, min( n.name_id ) FirstNameID
from name n
group by n.id ) FirstNames
on r.id = FirstNames.id
join name n2
on FirstNames.FirstNameID = n2.name_id
SELECT RECORD.id, RECORD.text, name.name, name.name_id
FROM RECORD
LEFT JOIN address
ON address.id = RECORD.id
LEFT JOIN name
ON name.id = RECORD.id
GROUP BY RECORD.id