SELECT table1.PrimaryKey(Some ID), table2.nameOfSomething
FROM table1
INNER JOIN table2
Here is the part i don't get :
USING(id)
this ID is table1 foreign key, and table2 primary key
i dont really get it..
table1.ID values:
25 Rows:
row 1-5 = 1 , row 6-10 = 2 , row 11-15 = 3 , row 16-20 = 4 , row 21-25 = 5
table2.ID values :
5 Rows:
row 1 = 1 , row 2 = 2 , row 3 = 3 , row 4 = 4 , row 5 = 5
i test it and i get different result without it, how comes?
Note : Table1 contains interests, Table2 contains categories for these interests
feel free to ask for more information
USING specifies that a join should be performed by joining on the listed columns in both tables. That is
SELECT t1.col1,
t1.col2,
t2.col1
FROM table1 AS t1
INNER JOIN table2 AS t2
USING (col1)
is the same as
SELECT t1.col1,
t1.col2,
t2.col1
FROM table1 AS t1
INNER JOIN table2 AS t2
ON t1.col1 = t2.col1
For reference, see the MySql homepage.
USING is a equi-join and relies on attribute names for the same data element remaining the same between tables.
ON is more flexible: because it requires you to explicitly specify the attribute name in both tables, attribute names for the same data element can be the same or they can be different between the tables. Also, it is a theta-join, meaning that the join type can be any condition, including equality. As a result of this flexibility, ON is more verbose.
| Table1: | Table2: |
| id | id | table1_id |
| 1 | 1 3 |
| 2 | 2 2 |
| 3 | 3 1 |
If you join the above two tables together with USING(id) it will match rows where the id value in Table1 are the same as the id value in Table2...
SELECT * FROM table1 JOIN table2 USING(id)
| id | id table1_id |
| 1 | 1 3 |
| 2 | 2 2 |
| 3 | 3 1 |
But, the id in Table2 might have nothing to do with the id in Table1. If that's the case, you can use ON to be specific about how you match records together...
SELECT * FROM table1 JOIN table2 ON table1.id = table2.table1_id
| id | id table1_id |
| 1 | 3 1 |
| 2 | 2 2 |
| 3 | 1 3 |
If you specify nothing at all, you match every record in one table, against every record in the other table...
SELECT * FROM table1 CROSS JOIN table2
| id | id table1_id |
| 1 | 1 3 |
| 1 | 2 2 |
| 1 | 3 1 |
| 2 | 1 3 |
| 2 | 2 2 |
| 2 | 3 1 |
| 3 | 1 3 |
| 3 | 2 2 |
| 3 | 3 1 |
Related
I'm trying to update one MySQL table based on information from another.
The original table where I would like to compare the values to the other table to be updated has a JSON object in it.
Here is what my tables look like
Original Table
Table1
id | programme
------------
1 | ["22","34"]
2 | ["10","11","12","13","14","15","17","18","19","20"]
Table to be updated
Table2
id | programme_id | table1_id
-----------------------------
1 | 22 |
2 | 18 |
3 | 12 |
UPDATE table2
INNER JOIN table1 USING (programme_id)
SET table2.table1_id = table1.id
Here is the expected output:
id | programme_id | table1_id
-----------------------------
1 | 22 | 1
2 | 18 | 2
3 | 12 | 2
set sql_safe_updates = 0;
update table2
inner join table1
on JSON_SEARCH(table1.programme,'one',table2.programme_id) is not null
set table2.table1_id = table1.id;
I want to select rows without duplicate values in columns. What I mean is that if there is a row with | 2 | 1 | and another one with | 1 | 2 | in the current selection, I want to show only one of them.
+------+------+
| id1 | id2 |
+------+------+
| 2 | 1 |
| 4 | 3 |
| 3 | 4 |
| 1 | 4 |
+------+------+
so in the example above it will select only first, last and either second OR third row.
and also to substitute these values with the string 'TITLE' from another table.
table values:
+----+----------+
| id | title |
+----+----------+
| 1 | title1 |
| 2 | title2 |
| 3 | title3 |
| 4 | title4 |
+----+----------+
so that the final select would have only titles in rows.
You can use least and greatest to do this. least gets the lower value of id1,id2 and greatest gets the greater of id1,id2.
select distinct least(id1,id2),greatest(id1,id2)
from t
Actually the above generates rows which aren't in the table. To avoid it, you need a left join with a derived table.
select t1.id1,t1.id2
from t t1
left join (select least(id1,id2) as id1,greatest(id1,id2) as id2
from t
group by least(id1,id2),greatest(id1,id2)
having count(*) > 1
) t2 on t2.id1=t1.id1 and t2.id2=t1.id2
where t2.id1 is null and t2.id2 is null
Edit: To get the title strings from a different table based on id's
select t1.id1,t1.id2,tt1.title,tt2.title
from t t1
left join (select least(id1,id2) as id1,greatest(id1,id2) as id2
from t
group by least(id1,id2),greatest(id1,id2)
having count(*) > 1
) t2 on t2.id1=t1.id1 and t2.id2=t1.id2
join titles tt1 on tt1.id=t1.id1 --use a left join if the titles table won't have all the id's
join titles tt2 on tt2.id=t1.id2 --use a left join if the titles table won't have all the id's
where t2.id1 is null and t2.id2 is null
From this tables:
table_a
id | date | owner | space
1 | 85408503 | 4 | 5
2 | 52345234 | 5 | 5
3 | 52345243 | 2 | 5
table_b
id | name | age
2 | luis | 32
4 | german | 53
5 | marta | 43
table_c
id | c_id | stack | vs
1 | 3 | 1 | 2
2 | 3 | 4 | 2
3 | 1 | 1 | 2
4 | 3 | 4 | 3
I want to select every field with a specific number in table_a.space (for example table_a.space = 5) GROUP BY t1.id joined with table_b.name, where owner = table_b.id and a new column that contain concatenated separated by comma the coincidence: table_a.id = table_c.c_id also table_c.version = 2
So.. My try ( i try a lot of things using group by, using , etc with no success
so just what works without error
SELECT t1.id,t1.owner,t3.vs
FROM table_a t1 LEFT JOIN table_b t2 ON t1.owner = t2.id
LEFT JOIN table_c t3 ON t1.id = t3.c_id
WHERE t1.space = 5 GROUP BY t1.id ORDER BY t1.id
I know this would put into a string (if I put this after "t1.owner," it would return just one row
GROUP_CONCAT(DISTINCT t3.stack SEPARATOR ',') as selected
and I don't know where to put the coincidence for t3.vs
AND t3.vs = 2
I would like this to return when t1.space = 5
id | owner| space | vs | selected
2 | 5 | 5 | 2 |
3 | 2 | 5 | 2 | 1,4
and this when t1.space = 3
and this should return
id | owner| space | vs |selected
3 | 2 | 5 | 2
You changed your naming convention in the middle of your question. What you want is to use GROUP BY
SELECT t1.id,t1.owner, GROUP_CONCAT(DISTINCT t3.stack SEPARATOR ',') as selected
FROM table_a t1 LEFT JOIN table_b t2 ON t1.owner = t2.id
LEFT JOIN table_c t3 ON t1.id = t3.c_id
WHERE t1.space = 5 AND t3.vs=2
GROUP BY t1.id
ORDER BY t1.id
Without the GROUP BY, you get everything grouped into 1 row. The group by tells mysql to group it by a particular column.
Given this table:
+----+-----------+--------+
| id | condition | values |
+----+-----------+--------+
| 1 | a | 1 |
+----+-----------+--------+
| 2 | a | 2 |
+----+-----------+--------+
| 3 | a | 3 |
+----+-----------+--------+
| 4 | a | 4 |
+----+-----------+--------+
| 5 | b | 5 |
+----+-----------+--------+
| 6 | b | 6 |
+----+-----------+--------+
How can I get a new table that begins on id=3 (including) and goes until condition = b (excluding):
+----+-----------+--------+
| id | condition | values |
+----+-----------+--------+
| 3 | a | 3 |
+----+-----------+--------+
| 4 | a | 4 |
+----+-----------+--------+
added fiddle: http://sqlfiddle.com/#!2/9882f7
Basically I want a table between a matching first condition (over a specific column - id) and a second one (over a different column - condition)
You need to stop thinking of SQL data as having any order. Think of SQL data in sets; you have to search by values, not by positions.
SELECT t1.*
FROM t AS t1
JOIN (
SELECT MIN(id) AS id FROM t
WHERE id >= 3 AND `condition` = 'b'
) AS t2
WHERE t1.id >= 3 AND t1.id < t2.id
ORDER BY t1.id
Something like this:
select t.*
from table t
where id >= 3 and id < (select min(t2.id) from table t2 where t2.condition = 'b');
EDIT:
This query works fine on the SQL Fiddle:
select t.*
from t
where id >= 3 and id < (select min(t2.id) from t t2 where t2.condition = 'b');
If I understand what you are asking for, I believe this will work for you:
SELECT id, condition, values
FROM tableName
WHERE id > 2
AND condition != b
ORDER BY id
I hope that works for you.
I am sure this would be easy to google if I knew the right words to use, but I've tried and not come up with anything: apologies if this is a common question on SO.
I have one table which lists a set of records which can be one of 4 types.
table_1:
+-------+------------+------+
| id | value | type |
+-------+------------+------+
| 1 | x | 1 |
| 2 | y | 1 |
| 3 | z | 2 |
| 4 | a | 3 |
+-------+------------+------+
I have another table which references the id of this table and stores data
table_2:
+-------+------------+------+
| id | table_1_id |value |
+-------+------------+------+
| 1 | 4 | A |
| 2 | 2 | B |
| 3 | 3 | C |
| 4 | 2 | D |
+-------+------------+------+
I want to write a query that effects:
"Find all the records from table 1 which are of type 1, take the id's of those records, and find all the records in table 2 where 'table_1_id' which match one of that set of ids."
In the above very oversimplified table example that would result in the query returning records with ids 2 and 4 in table 2
Sounds like your looking for IN:
select *
from table2
where table_1_id in (select id from table1 where type = 1)
Or perhaps you could JOIN the tables:
select t2.*
from table2 t2
join table1 t1 on t2.table_1_id = t1.id
where t1.type = 1
Joining the tables could result in duplicate records. Depends on your needs.
SELECT t1.value,t1.type,t2.value FROM table1 t1,table2 t2 WHERE t1.id = t2.table_1_id AND t1.type = 1;