Querying two tables with an union - mysql

I have a very simple mysql query, I want to fetch some 'data' from two tables table1 and table2 as soon as this 'data' is in one row containing a precise 'id', so I ran a prepared request :
'select data from (
select data from table1 union select data from table2)
where id = :id'
But it doesn't seem to work (btw, I tried simply 'select data from table1, table2 where id = :id ')
but it didn't work. Someone could help, I don't know where I am missing something ?

select * from table1 where id = :id
union all
select * from table2 where id = :id

Unions are complex and unwarranted in MySQL, I would rather rely on JOIN to execute my statements.

I think what you're looking for is a join. There are multiple types of joins, where the most common are LEFT JOIN and INNER JOIN.
LEFT JOIN returns the rows, even if the matched data does not exists, and return null for the joined data.
INNER JOIN requires the matched data to exists and doesn't return anything if the matched data doesn't exist.
Example using INNER JOIN:
SELECT
table1.*,
table2.*
FROM
table1
INNER JOIN table2 ON ( table1.id = table2.id )
WHERE
id = :id

Select table1.data, table2.data from table1 where table1.id = table2.id

Related

Specify table-column on "in" operator

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.

SQL - show results from table without values from another table

I need to show only results which are in Table1 and Table2 but are not in Table3. Basically, it should be something like TABLE1, Table2 except INNER JOIN between (TABLE1, Table2) and TABLE3.
Should looks like this - On left side Table1 and Table2, on right side Table3
Now I have this:
SELECT mesta_email, mesta_kod
FROM Table1
UNION ALL
SELECT mesta_email, mesta_kod
FROM Table2
// And somehow except values which are in Table3
Can somebody help me please? Thanks a lot.
There are a couple different ways to do this. I believe mysql does better with the outer join/null approach:
select t.*
from (
SELECT mesta_email, mesta_kod
FROM Table1
UNION ALL
SELECT mesta_email, mesta_kod
FROM Table2
) t left join Table3 t3 on t.mesta_email = t3.mesta_email
and t.mesta_kod = t3.mesta_kod
where t3.mesta_email is null
This assume table3 shares the same structure as the other 2 tables.
I would approach the problem almost directly as you write it, using exists and not exists:
select t1.mesta_email, t2.mesta_kod
from table1 t1
where exists (select 1
from table2 t2
where t2.mesta_email = t1.mesta_email and t2.mesta_kod = t1.mesta_kod
) and
not exists (select 1
from table3 t3
where t3.mesta_email = t1.mesta_email and t3.mesta_kod = t1.mesta_kod
);
One advantage of exists/not exists over other approaches involves duplicates. If one of the tables (say table1) has not duplicates, but the others might, there is no need to remove duplicates in the resulting data set.

Looking for an alternative SQL command to find the same values in two tables

I am using this command to find the same values in two tables when the tables have 100-200 records. But When the tables have 100000-20000 records, the sql manager, browsers, shortly the computer is freesing.
Is there any alternative command for this?
SELECT
distinct
names
FROM
table1
WHERE
names in (SELECT names FROM table2)
Try with join
SELECT distinct t1.names
FROM table1 t1
join table2 t2 on t2.names = t1.names
Use EXISTS:
SELECT distinct t1.names
FROM Table1 t1
WHERE EXISTS(
SELECT 1 FROM tabl2 t2 WHERE t2.names=t1.names
)
SELECT DISTINCT t1.names
FROM table1 t1
INNER JOIN table2 t2 on t1.names=t2.names
The use of the INNER JOIN ensures that there are only exact matches returned from both tables. It should be relatively quick, but indexes may be required over the long term, especially if you're using them for other JOINs and GROUP BYs etc.
a simple join will also do it.
make sure the column is indexed.
select distinct t1.names
from table1 t1, table2 t2
where t1.names = t2.names
Show names from both tables where there is a match
SELECT names
FROM table1
UNION ALL
SELECT names
FROM table2
This query will return duplicated values if there are any. If you only want distinct values then try this but note that there will be an impact on performance
SELECT names
FROM table1
UNION
SELECT names
FROM table2
SELECT table1.names
FROM table1
INNER JOIn table2
ON table1.names = table2.names
Group By table1.names

How to join only one column?

SELECT * FROM table1
LEFT JOIN table2
ON table1.id = table2.table1_id
WHERE table1.id = 1
I need to join only one column from table 2, say first_name.
How can I do that?
Assuming that you mean "select one column from table 2":
SELECT table1.*, table2.first_name
FROM table1
LEFT JOIN table2
...
The accepted answer is the correct answer but I have encountered a strange error when the tables are in two different databases:
Assuming that table1 is in database1 and table2 is in database2.
Initially I have tried this:
SELECT *, database2.table2.first_name
FROM table1
LEFT JOIN database2.table2
ON database1.table1.id = database2.table2.table1_id
WHERE table1.id = 1
The strange thing is that if I try this query from PHP PDO there were no errors but the result contained all columns from database2.table2 (expected only first_name column).
But if I have tried the same query from phpmyadmin got a sintax error:
Table 'database2.table1' doesn't exist
So, for solve that, then all databases need to be specified implicitly like this:
SELECT database1.table1.*, database2.table2.first_name
FROM database1.table1
LEFT JOIN database2.table2
ON database1.table1.id = database2.table2.table1_id
WHERE database1.table1.id = 1
Take your original code and substitute * with table1.*, table2.YourChosenColumn
SELECT table1.*, table2.YourChosenColumn
FROM table1 LEFT JOIN table2
ON table1.id = table2.table1_id
WHERE table1.id = 1
Do you mean in addition to your already stated query:
SELECT * FROM table1
LEFT JOIN table2
ON table1.id = table2.table1_id
WHERE table1.id = 1 and table1.first_name = table2.first_name

Change mysql table join based on field value

Is it possible in MySQL to change the JOIN of a table based on whats in a particular field of a record?
Example:
SELECT
CASE table0.status
WHEN 1 THEN table1.id
WHEN 2 THEN table2.id
END
FROM
table0, table1, table2
IF (table0.status = 1, INNER JOIN queue ON table1.id = table0.product, INNER JOIN queue ON table2.id = table0.product)
I need the joined table to be table1 if the value for 'product' in table0 = 1 or table2 if the value for 'product' in table0 is 2.
When I try the above example I only get mysql syntax errors. Ive also tried it with CASE statement instead of the IF but still not working.
I think a subselect will be a better solution than JOIN in this case. You can use a CASE statement with a SELECT inside it.