Insert on 3 joins MYSQL - mysql

What I am trying to do is to insert records from multiple tables into 1 table by joining. Here is what I have and I can't seem to get it to work. I get the following error #1136 - Column count doesn't match value count at row 1
INSERT INTO users(`name`, `email`,`location_id`, `department_id`)
VALUES('John Doe', 'jdoe#email.com', 1, 1)
INSERT INTO extensions(`ext`)
VALUES(98765)
INSERT INTO dids(`did`)
VALUES('1-800-555-5555')
INSERT INTO users_numbers(user_id,ext_id,did_id)
SELECT extensions.*, dids.*, users.*
FROM extensions tbl_ext, dids tbl_dids, users tbl_users, users_numbers usn
Inner Join users ON users.id=usn.user_id
Inner Join extensions ON extensions.id=usn.ext_id
Inner Join dids ON dids.id=usn.did_id
WHERE tbl_users.name = 'John Doe'
AND tbl_users.email = 'jdoe#email.com'
AND tbl_ext.ext = 98765
AND tbl_dids.did='401-559-9999';
The first 3 insert statements work. The error fires on the 4 insert when I try to join. Can anyone help.

Use LAST_INSERT_ID():
INSERT INTO users(`name`, `email`,`location_id`, `department_id`)
VALUES('John Doe', 'jdoe#email.com', 1, 1);
SET #user_id = LAST_INSERT_ID();
INSERT INTO extensions(`ext`)
VALUES(98765);
SET #ext_id = LAST_INSERT_ID();
INSERT INTO dids(`did`)
VALUES('1-800-555-5555');
SET #did_id = LAST_INSERT_ID();
INSERT INTO users_numbers(user_id,ext_id,did_id)
VALUES (#user_id,#ext_id,#did_id);
Instead of using user variables (#user_id,#ext_id,#did_id) you can also fetch the LAST_INSERT_ID in your application language.

There are two problems.
First, the SELECT list has to return only the columns that you want to insert into the table. The error is because you're returning tablename.* rather than specific columns.
Second, the SELECT query is very wrong. You have the tables that you're joining listed twice: first in the FROM clause and then again in the INNER JOIN clauses. You should only list them once (unless you're doing a self-JOIN, which is not needed here).
And you shouldn't be joining with users_numbers -- that's the table you're trying to add to, so it doesn't have the IDs for these rows yet.
What you want is a simple cross join between the rows from each of the source tables that match the values you're combining into the relation table.
INSERT INTO users_numbers(user_id,ext_id,did_id)
SELECT u.id, e.id, d.id
FROM users AS u
CROSS JOIN extensions AS e
CROSS JOIN dids AS d
WHERE u.name = 'John Doe'
AND u.email = 'jdoe#email.com'
AND e.ext = 98765
AND d.did='401-559-9999';

You need to be very specific about which columns you want from that SELECT. Right now you're grabbing everything from the three tables, that's too much.
Maybe you mean:
INSERT INTO users_numbers(user_id,ext_id,did_id)
SELECT users.id, extensions.id, dids.id
FROM ...
When composing complicated queries like this, run the SELECT subcomponent separately to ensure it produces the right data. I bet if you ran your version it'd show a bunch of columns.

Related

return values of table 1 based on single column in table 2

I have 3 tables that I am using and need to make a query to return data from one table based on the value of a single column in the second table.
tbl_user
ID
login
pass
active
mscID
tbl_master
ID
name
training_date
MSCUnit
Active
tbl_msc
mscID
mscName
my current SQL statement:
SELECT
tbl_master.ID,
tbl_master.name,
tbl_master.training_date,
tbl_master.MSCUnit,
tbl_master.active,
tbl_user.mscID
FROM
tbl_master,
tbl_user
WHERE
tbl_master.active = 1 AND tbl_master.MSCUnit = tbl_user.mscID
The values stored in tbl_msc.mscID is a varchar(11) and it contains a string similar to A00 or A19. This is also the Primary key in the table.
The values stored in tbl_user.mscID matches that of tbl_msc.mscID. The values stored in tbl_master.UnitMSC also matches that of tbl_msc.mscID.
My goal is to return all records from tbl_master where the currently logged in user has the same mscID. The problem I am having is the statement returns all records in tbl_master.
I have tried several different join statements and for some reason, I cannot get this to filter correctly.
I am missing something. Any assistance in the SQL statement would be appreciated.
Thanks,
Will
You should be writing this using joins. I don't know how you know who the current user is, but the idea is to join the three tables together:
SELECT m.ID, m.name, m.training_date, m.MSCUnit, m.active,
u.mscID
FROM tbl_master m JOIN
tbl_user u
ON m.MSCUnit = u.mscID JOIN
tbl_msc msc
ON msc.mscID = u.msc_ID
WHERE m.active = 1 AND msc.mscName = ?;
Notice the use of proper, explicit, standard JOIN syntax and table aliases.
Select a.*, b.userid from
table_master a, table_user b where
a.mscunit in (select mscid from
table_user where active=1)
This should point you in the right direction.

Why am i getting "Subquery returns more than 1 row"

Hi I am making a webrowser game and I am trying to get monsters into my data base when I get the error:
Subquery returns more then 1 row
here is my code
INSERT INTO monster_stats(monster_id,stat_id,value)
VALUES
( (SELECT id FROM monsters WHERE name = 'Necroborg!'),
(SELECT id FROM stats WHERE short_name = 'atk'),
2);
any ideas how to fix this problem?
Try use LIMIT 1
INSERT INTO monster_stats(monster_id,stat_id,value) VALUES ((SELECT id FROM monsters WHERE name = 'Necroborg!' LIMIT 1),(SELECT id FROM stats WHERE short_name = 'atk' LIMIT 1),2);
Or you could use Insert from select, with join, if you have relations with 2 tables.
INSERT INTO monster_stats(monster_id,stat_id,value)
(SELECT monsters.id, stats.id, 2 as value FROM monsters
LEFT JOIN stats on monsters.id = stats.monsters_id
WHERE monsters.name = 'Necroborg!'
AND stats.short_name = 'atk'
)
MYSQL insert from select:
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
The problem is one or both of the following:
There is more than one monster named 'Necroborg!'.
There is more than on stat named 'atk'.
You need to decide what you want to do. One option (mentioned elsewhere) is to use limit 1 to get only one value from each statement.
A second option is to better specify the where clause so you get only one row from each table.
Another is to insert all combinations. You would do this with insert . . . select and a cross join:
INSERT INTO monster_stats(monster_id, stat_id, value)
SELECT m.id, s.id, 2
FROM (SELECT id FROM monsters WHERE name = 'Necroborg!') m CROSS JOIN
(SELECT id FROM stats WHERE short_name = 'atk');
A third possibility is that there is a field connecting the two tables, such as monster_id. But, based on the names of the tables, I don't think that is true.

Delete values in one table based on values in another table

I was trying to execute this statement to delete records from the F30026 table that followed the rules listed.. I'm able to run a select * from and a select count(*) from with that statement, but when running it with a delete it doesn't like it.. it gets lost on the 'a' that is to define F30026 as table a
delete from CRPDTA.F30026 a
where exists (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));
Thanks!
This looks like an inner join to me, see MySQL - DELETE Syntax
delete a from CRPDTA.F30026 as a
inner join CRPDTA.F4101 as b on a.IELITM = b.IMLITM
where substring(b.IMGLPT, 1, 2) not in ('FG', 'IN', 'RM')
Please note the alias syntax as a and as b.
Instead of the 'exists' function, you can match the id (like you do in the where clause):
delete from CRPDTA.F30026 a
where a.IELITM IN (
select b.IMLITM from CRPDTA.F4101 b
where a.IELITM=b.IMLITM
and substring(b.IMGLPT,1,2) not in ('FG','IN','RM'));
I believe this is what you really want, all IELITMs which meet your criteria.
delete from CRPDTA.F30026
where IELITM IN (
select IMLITM from CRPDTA.F4101
where substring(IMGLPT,1,2) not in ('FG','IN','RM'));

Multiple Row Inserion via subQuery

i am trying to insert multiple rows using a subquery but it gives and error "SubQuery Returns more than 1 rows"
scenario is that i want to add comment against every test of a subdepartment, i am getting all test id's via subquery but i not being able to iterate over id's and insert comment against each test. Here is my SQL Query
INSERT INTO dc_tp_comment (labid,branchid,Comment,testid,lastupdated,enteredby)
Values('abcd',101,'comment here',(select T.testid
from dc_tp_test T
Inner Join dc_tp_subdepartments S
on T.subdepartmentid = S.subdepartmentid
Where S.subdepartmentid = 13),sysdate(),1)
You cannot use subselect in just one column, use them for whole row:
INSERT INTO dc_tp_comment (labid,branchid,Comment,testid,lastupdated,enteredby)
select 'abcd',101,'comment here', T.testid, sysdate() , 1
from dc_tp_test T Inner Join dc_tp_subdepartments S
on T.subdepartmentid = S.subdepartmentid
Where S.subdepartmentid = 13
Use select insted of values if you want to insert multiple rows...
Syntax would be like:
INSERT INTO dc_tp_comment (labid,branchid,Comment,testid,lastupdated,enteredby)
select 'abcd',101,'comment here',(select T.testid
from dc_tp_test T
Inner Join dc_tp_subdepartments S
on T.subdepartmentid = S.subdepartmentid
Where S.subdepartmentid = 13),sysdate(),1

How to insert only edited values in table

I have table "nol_voa" with different values and I am importing xml file with values in that table I want to insert in another table "#tmpRcIzm" the "id" values where the field "C_REF" has changed its value.
This is the code, what I wrote, but there is a mistake, it always adds two more "id" values which have not been changed.
insert into #tmpRcIzm
select distinct
a.id
from
openxml(#hDoc, '/art_komplekts/nol_voa') with #vc xd
join nol_art a on xd.art_cd = a.cd
left join #tmp t on t.cd = xd.art_cd
inner join nol_voa v on xd.id_art = v.id_art
where
xd.C_REF!=v.C_REF
You left join of #tmp, can introduce duplicates, and also the join on nol_art serve no purpose on this SQL. remove those two, and you should elminate your dups.