SQL INSERT INTO with JOIN - mysql

I'm trying to come up with a MySQL query that will insert data in a table with data from a other table.
That's my structure:
table1:
ID killerid playerid weapon
table2:
ID playername
Now I want to insert into table1 in collumn killerid and playerid the IDs of the two names in a where clause.
But it won't work..
INSERT INTO table1 (killerid)
SELECT
t1.id
FROM
table1 t1
LEFT JOIN
table2 t2 ON (t2.killerid = t1.id)
WHERE t2.playername = 'example'
Better to understand:
I hope thats a little bit better to understand:
There is my table USERS
ID | playername [...]
-----|-------------------
1 | example1
2 | example2
And there is my table KILLS
ID | killerid | victimid | weapon
-----|----------------------------------
1 | 1 | 2 | FIST
2 | 2 | 1 | PISTOL
I want to insert into KILLERS the IDs of the killer (killerid) and the victim (victimid) but I only have the 2 names (example1 and example2) when I'm inserting.
So I have to get the IDs of that 2 names in my table USERS.
Like (pseudo example):
INSERT INTO `KILLERS`(`killerid`, `victimid`, `weapon`)
VALUES(
USERS.ID WHERE USERS.playername = 'example1',
USERS.ID WHERE USERS.playername = 'example2',
'FIST'
);
That should be insert following:
ID | killerid | victimid | weapon
-----|----------------------------------
1 | 1 | 2 | FIST
I hope that's clear.

Given the data you've got it looks like you can get part way there as follows:
INSERT INTO table2(killerid, playerid, weapon)
SELECT t1.id as killerid, -- the 'as killerid' is not required but is useful
t1.playerid, -- to help understand what's intended
t1.weapon
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t2.killerid = t1.id
WHERE t2.playername = 'example'
EDIT
Now that we've got a table structure the solution is much easier to figure out.
INSERT INTO kills (killerid, victimid, weapon)
SELECT u1.ID as killerid,
u2.ID as victimid,
d.weapon
FROM USERS u1
INNER JOIN USERS u2
ON 1 = 1
INNER JOIN (SELECT 'FIST' as weapon
FROM DUAL) d
ON 1 = 1
WHERE u1.playername = 'example1' AND
u2.playername = 'example2';
SQLFiddle here
Share and enjoy.

your sql says:
you need have in varo_lastkills table some values like varo_users table, if you don't have congruent values your query don't run

Related

How to preprocess info to match the join in the query

I have two tables, that I would like to link by its type field.
table1
id | type
---+--------
1 | One
2 | Two
3 | Three
4 | Four
5 | Two
table2
id | type
---+------
34 | N
35 | Z
26 | Y
27 | W
And the equivalent table is (this table does not exist and cannot exist)
One = Z
Two = Y
Three = N
Four = W
And my query is
SELECT t1.type
FROM table1 t1, table2 t2
WHERE t1.type = t2.type
Probably the best solution will be change the information in one of the tables. But I cannot do that, I also can't create any store procedure.
I would like to have just one query to do this.
Any idea?
You can synthesize the relationship table in the query:
SELECT t1.id AS id1, t1.type, t2.id AS id2
FROM table1 AS t1
JOIN (
SELECT 'One' AS `long`, 'Z' AS short
UNION ALL
SELECT 'Two', 'Y'
UNION ALL
SELECT 'Three', 'N'
UNION ALL
SELECT 'Four', 'W'
) AS r ON t1.type = r.long
JOIN table2 AS t2 ON t2.type = r.short
DEMO
Probably the best solution will be change the information in one of the tables. But I cannot do that, I also can't create any store procedure. I would like to have just one query to do this.
You don't necessarily have to change the information in one of the two tables. You could create a table which contains the relationships between the two types, i.e.:
table3
type1 | type2
------+------
One | Z
Two | Y
Three | N
Four | W
Then you could write a query like this:
SELECT table1.type
FROM table1
JOIN table3
ON table1.type = table3.type1
JOIN table2
ON table3.type2 = table2.type

How do I create a relation between tables using an interval comparison in MySQL?

I would like to create a relationship between two tables based on whether a value in one table falls in a an interval in the other. One table 1 is ~16000 rows:
name | start | end
-----------------------------------------
someName | startPosition | endPosition
table 2 is ~20000000 rows:
id | location
--------------------------
someID | positionInteger
Each id falls in the interval of exactly one name, but each name can have many ids associated with it.
I would like to add a new index to table 2 so that it becomes:
id | location | name
---------------------------------
someID | positionInteger | someName
I've tried doing:
ALTER TABLE table2 ADD INDEX name (name);
With a bit of python I can get all the names in the database and then for each name and interval:
SELECT someID FROM table2 WHERE location >= startPosition AND location <= endPosition
Then I can loop through the resulting IDs and:
UPDATE table2 SET name = 'someName' WHERE id = 'someID'
This works but is very slow. Is there a more efficient way to do this using MySQL and avoiding multiple loops?
Join the tables
SELECT t2.id, t2.location, t1.name
FROM Table1 AS t1
JOIN Table2 AS t2 ON t2.location BETWEEN t1.startPosition AND t1.endPosition
You shouldn't be adding an index to table 2, you should be adding a column:
ALTER TABLE Table2 ADD COLUMN name VARCHAR(32); -- Replace this with the actual size
Then you can update all the rows with a similar join:
UPDATE Table2 AS t2
JOIN Table1 AS t1 ON t2.location BETWEEN t1.startPosition AND t1.endPosition
SET t2.name = t1.name
You can use LEFT JOIN :
SELECT id,location,name FROM table2 as t2
LEFT JOIN table1 as t1
ON t2.location BETWEEN t1.`start` AND t1.`end`;
More details http://sqlfiddle.com/#!9/721e5/1

mySQL combining two tables I get more results

I have one table of like this
user|itemID
and another table like this:
itemID | itemTrait1 | itemTrait2 etc...
I am trying to link the tables in one query which should be simple. I conduct the query like so:
SELECT * FROM Table1, Table2 WHERE Table1.userID = 1 AND Table1.itemID = Table2.itemID;
The issue is that I am getting 456 results returned but if I simply run:
SELECT * FROM Table1 WHERE userID = 1;
I get 434 results. Should both these statements get the same number of results returned?
How I imagine this call working is that for every entry in Table 1 for user 1 it connects it to the item's data in Table2? I think I am missing something here.
Query to combine both tables based in itemID
select * from table1 t1
left join table t2 on t1.itemID = t2.itemID
where t1.itemID = 1;
if you are getting the more records than the records that of table1 then your second table table2 must have multiple records for itemID. for example
Table1
user | itemId
---------------
1 | 1
Table2
itemId | itemTrait1 | itemTrait2
----------------------------------------
1 | A | B
1 | C | D
now when you will apply join here it will join itemID 1 with two items of second table.

mySQL multiple cross reference select query

I'm trying to select the names of products stored in as an ID list in columns a different table. There are 20 columns to lookup so my normal approach would make a huge query. Can someone suggest a simple way to do this?
Table1:
id | productName
Table2
id | p1 | p2 | p3 | p4... up to p20
p1 - p20 each contain an ID number of a product from table1
I need to select rows in table2, replacing p1-p20 with the corresponding productName from table1
Thanks!
Can someone suggest a simple way to do this?
I guess this is a simple way:
SELECT
Table2.id,
T1.productName,
T2.productName,
T3.productName,
-- etc...
FROM Table2
JOIN Table1 T1 ON Table2.p1 = T1.id
JOIN Table2 T2 ON Table2.p1 = T2.id
JOIN Table3 T3 ON Table2.p1 = T3.id
-- etc...
Yes, this is a huge query, but it is simple.
You might want to reconsider your database design. Here's a suggestion:
Table1:
id | productName
Table2
id | index | productid
1 1 p1
1 2 p2
1 3 p3
...etc
Query like this:
SELECT id, index, productName
FROM Table2
JOIN Table1
ON Table2.productid = Table1.id

SQL Query: Joining two tables where entity of the first table has no, or multiple entries in other table

I have to database tables, where entities of the first Table may or may not have associated entries in the second table:
Table 1 Table 2
+-----+-----+ +-----+-------+-------+
| ID | ... | | ID | T1_ID | NAME |
+-----+-----+ +-----+-------+-------+
| 1 | ... | | 1 | 1 | p1 |
| 2 | ... | | 2 | 1 | p2 |
| 3 | ... | | 3 | 2 | p1 |
| 4 | ... | +-----+-------+-------+
+-----+-----+
I have the following queries i need to run:
Get all entities of Table_1 with a specific entry of Table_2 - That's easy, a simple Join will do...
Get all entities of Table_1, which don't have a specific entry of Table_2 associated - not so easy, but i also managed to query this with a join.
Get all entities of Table_1, which have a specific entry (A) and don't have another specific entry (B) associated, i.e. get all entities of Table_1 that have an entity of Table_2 with name=p1 and don't have an entity of Table_2 with name=p2 associated.
Is it possible to accomplish the kind of query from (3) in a single sql-statement without a sub-query?
Get all entities of Table_1, which
have a specific entry (A) and don't
have another specific entry (B)
associated, i.e. get all entities of
Table_1 that have an entity of Table_2
with name=p1 and don't have an entity
of Table_2 with name=p2 associated.
I'm having a bit of trouble understanding your criteria, but I think that is what you want:
SELECT *
FROM Table1 t1
JOIN Table2 t2 ON t1.ID = t2.t1_id
WHERE t2.name = 'p1'
AND NOT EXISTS(SELECT 'x' FROM Table2 t2_2 WHERE t1.ID = t2_2.t1_id AND t2_2.name = 'p2')
That will give you everything from Table1 that has a matching record in Table2 with name = 'p1' and DOESN'T have a matching record in Table2 with name = 'p2'. Is that what you need?
EDIT AGAIN:
I thought of a smarter way to do this that involves a static (non-correlated) subquery. This subquery will only be executed one time, rather than being executed once for every parent row in Table1. I didn't put this code through a query analyzer, but it should be significantly faster than of the queries using EXISTS(...)
SELECT *
FROM Table1 t1
JOIN Table2 t2 ON t1.ID = t2.t1_id
WHERE t2.name = 'p1'
AND t1.id NOT IN(SELECT t1_id FROM Table2 WHERE name = 'p2')
You can use an EXISTS subquery (effectively the same as doing two joins).
SELECT * FROM Table_1 AS t1
WHERE EXISTS (SELECT * FROM Table_2 AS t2 WHERE t1.Id = t2.Id AND Name='p1')
AND NOT EXISTS (SELECT * FROM Table_2 AS t2 WHERE t1.Id = t2.Id AND Name='p2')
To get all occurrences where t2 matches t1.id but not some other field do
SELECT t1.id, t2.id FROM table2 t2
INNER JOIN table1 t1 ON (t2.t1_id = t1.id AND not(t2.fieldx <=> t1.fieldx))
Note that this will also exclude rows where both fieldx are null.
If you don't want that substitute the <=> with =.
To make the variation of solutions more complete:
SELECT t1.*
FROM Table_1 t1
INNER JOIN Table_2 it2 ON t1.ID = it2.T1_ID AND it2.NAME = 'p1'
LEFT JOIN Table_2 lt2 ON t1.ID = lt2.T1_ID AND lt2.NAME = 'p2'
WHERE lt2.ID IS NULL