i would like to know if there is any shortcut to specify the column where IN have to check for matches.
Example:
Instead of this:
select *
from table1
where id in(
select column
from table2
)
something like this:
select *
from table1
where id in table2.column
I know the existence of TABLE for IN, ANY, SOME to specify a table, but it works only if the table specified is composed by just 1 column
EDIT: using join is not an option, because the real use i was looking for is on a NOT IN operator, and also JOIN create duplicates sometimes like in a one to many relation
There is no shortcut like that in SQL. Let me explain why.
In a query, all table references need to be made in the FROM clause. Hence, you cannot simply refer to table2.col unless table2 has been defined in the FROM clause. table2 is actually an alias, which defaults to the table name.
From a performance perspective, I would recommend exists:
select t1.*
from table1 t1
where exists (select column
from table2 t2
where t2.column = t1.id
)
In particular, this can take advantage of an index on table2(column) and has the same semantics as in.
Using a JOIN is a bit shorter. At least it does not require a subquery or another SELECT ... FROM.
SELECT table1.*
FROM table1
JOIN table2 ON table1.id = table2.column
Although this simple example is an inner join, not a semi-join. An inner join is different because it produces one row per matched row in table2. A semi-join only produces one row for each row in table1, even if it matches multiple rows in table2.
If you want to simulate a semi-join, use DISTINCT to reduce the result to one row per row of table1:
SELECT DISTINCT table1.*
FROM table1
JOIN table2 ON table1.id = table2.column
If you want to check for something like NOT EXISTS, use an exclusion join:
SELECT table1.*
FROM table1
LEFT OUTER JOIN table2 ON table1.id = table2.column
WHERE table2.column IS NULL
No need to use DISTINCT on the outer join example. There will be no row duplication from the join, because it can only "match no rows" once.
Related
I have two joined tables:
SELECT table1.*, table2.* FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.t1_id
The question: In query results, id will always be taken from secondary table defined in SELECT statement?
For example:
if I use select t1.*, t2.* - in results id will be t2.id
if I use select t2.*, t1.* - id will be t1.id.
Is this good practice to use 'merged' result, or should I avoid ambiguity, and always define columns strictly?
No, the sql query will return all columns with the same name from all tables, not just the last one, unless you use a natural join (table1 inner join table2 using(column)).
If you use some kind of a component that stores the results in associative arrays, then these components usually use only the field names as key, therefore they return only the last column's value from those that have the same name.
However, it is a good practive to use an alias if you want to return more than 1 column that has the same name in the database.
My suggestion is to use tablename with alias and get to use like this. It would be best practice to run query.Mention your column names even though it has many columns. You can order your display.
SELECT t1.columnName1, t2.columnName2 FROM tablename1 t1 INNER JOIN tablename2 t2 ON t1.id = t2.id
I have 2 tables in the same database.
I want to merge them based on the common id column. Because the tables are too huge I am not sure if there are duplicates.
How is it possible to merge these two tables into one based on the id and be sure that there are no duplicates?
SELECT *
FROM table1,table2
JOIN
GROUP BY id
What do you mean by merging two tables? Do you want records and columns from both the tables or columns from one and records from both?
Either way you will need to change the join clause only.
You could do a join on the columns you wish to
SELECT DISTINCT *
FROM table1 tb1
JOIN table2 tb2
ON table1.id = table2.id
Now if you want columns from only table1 do a LEFT JOIN
If you want columns from only table2 then a RIGHT JOIN
If you want columns from both the tables, use the query as is.
DISTINCT ensures that you get only a single row if there are multiple rows with the same data (but this distinct will check values for all columns in a row whether they are different or the same)
Union won't help if both tables have different number of columns. If you don't know about joins then use a Cartesian product
select distinct *
from table1 tb1, table2 tb2
where tb1.id = tb2.id
Where id is the column that is common between the tables.
Here if you want columns from only table1 do
select distinct tb1.*
Similarly replace tb1 by tb2 in the above statement if you just want table2 columns.
select distinct tb2.*
If you want cols from both just write '*'
In either cases I.e. joins and products said above if you need selective columns just write a table alias. E.g.
Consider :
table1 has id, foo, bar as columns
table2 has id, name,roll no, age
you want only id, foo, name from both the tables in the select query result
do this:
select distinct tb1.id, tb1.foo, tb2.name
from table1 tb1
join table2 tb2
on tb1.id=tb2.id
Same goes for the Cartesian product query. tb1, tb2 are BTW called as a table aliases.
If you want data from both the tables even if they have nothing in common just do
select distinct *
from table1 , table2
Note that this cannot be achieved using a join as join requires a common column to join 'on'
I am not sure What exactly do you want but anyway, this is your code
SELECT *
FROM table1,table2
JOIN
GROUP BY id
i just edit your query
SELECT *
FROM table1 JOIN table2
on table2.id = table1.id
GROUP BY table1.id // here you have to add table
//on which you will be group by at this moment this is table1
Try UNION:
https://dev.mysql.com/doc/refman/5.0/en/union.html
IT is very simple. Hope it will help.
Also you should have a look at "DISTINCT".
I have two interconnected tables: one stores some general result (table1), the other one details N rows for each result (table2).
Each record in table2 has a field recording the "auto_id" of the table1 row of reference (field is called "ref_id")
I intentionally deleted some records from the table1, but I left the referenced rows in table2.
How can I find all rows with invalid "ref_id"s in table2 that link to a no more existing "auto_id" in table1?
I was thinking something like
SELECT *
FROM table2
WHERE NOT EXISTS(
SELECT auto_id
FROM 'table1'
WHERE 'table2.res_id' = auto_id
)
but there-s obviously some error.
Thanks for the help!
You are using the wrong quotes. Single-quotes (apostrophes, or ASCII 39) are for literal strings. The easiest solution would be to remove the quotes:
SELECT *
FROM table2
WHERE NOT EXISTS(
SELECT auto_id
FROM table1
WHERE table2.res_id = auto_id
);
If you want to quote identifiers in MySQL, use backticks (ASCII 96).
SELECT *
FROM `table2`
WHERE NOT EXISTS(
SELECT auto_id
FROM `table1`
WHERE `table2`.`res_id` = `auto_id`
);
The cleanest way IMHO is an outer join filtering for missing rows:
SELECT t2.*
FROM table2
LEFT JOIN table1 t1 ON t1.auto_id = t2.res_id
WHERE t1.auto_id IS NULL
This works because missed left joins have all nulls in their columns and where clause conditions are applied after the join is made - the IS NULL condition means the only rows returned are those that don't have a matching row in the other table.
As well as being the most efficient (assuming an index on table1.auto_id), it also makes for a briefer query than a NOT IN (...) query.
MySQL JOIN is the best option for you.
Try this:
SELECT *
FROM table2 T2
JOIN table1 T1
ON T2.`res_id` != T1.`auto_id`
I have two tables,
table1 and table2 both tables has these columns
id, name, rel_id
now i would like to have a query to count ids of the table1 where name from table2 is equals to john and table1 rel_id equals to table2 rel_id.
so something like this (this is not correct that's why i need help to make it work).
Select count(ids) from table1
where table2.name="john"
and table1.rel_id=table2.rel_id
Well, one way is to use a join:
Select count(t1.id)
from table1 t1 join
table2 t2
on t1.rel_id = t2.rel_id
where t2.name = 'john';
Note that this uses table aliases to distinguish all the columns in each table. Because the tables have the same columns, you need to identify the table for each column. Also, the I changed the string constant to use single quotes rather than double quotes.
You need to look into joins so :
select count(ids)
from table1 join table2 on table1.rel_id=table2.rel_i
where table2.name="john"
A short intro from W3C schools: http://www.w3schools.com/sql/sql_join.asp
The full MySQL URL for more reference http://dev.mysql.com/doc/refman/5.0/en/join.html
Can anyone explain to me why they use AS id and AS r2 and USING id on the codes :
SELECT id, username FROM friendship JOIN (SELECT CEIL(RAND() * (SELECT MAX(id) FROM friendship)) AS id) AS r2 USING (id);
I just want to know the purpose of using them, why using them?
The As is just to create an Alias for the subquery, that way you can use that same alias 'id' with the using command.
Basically the query wants the friendship table to join the subquery on the id column, since the subquery only returns one result it can join with the id column in the friendship table.
OscarMk already explained the AS, but the USING is the equivalent of ON table1.id = table2.id. By using USING (a bit redundant here...), your RDBMS basically merge the columns into a single one, which means you don't have to tell your RDBMS if you want the column from table1 or table2. Simple example :
SELECT table1.id
FROM table1
INNER JOIN table2
ON table1.id = table2.id;
SELECT id
FROM table1
INNER JOIN table2
USING (id);
Those queries are equivalent. If you had forgotten to use table1.id in the first query, your RDBMS would have raised an error.
You can usually do a NATURAL JOIN instead of a INNER JOIN, and not use a USING or ON clause at all (that's what NATURAL JOIN are for)