I have a SQL query:
SELECT table1.column1, table2.column2, table1.column2
FROM table1 LEFT JOIN table2 (ON table1.column1=table2.column2)
What I want to do is add another left join to the table but also to count in that left join data like:
SELECT table1.column1, table2.column2, table1.column2, COUNT(table3.column1)
FROM table1 LEFT JOIN table2 ON table1.column1=table2.column2
LEFT JOIN table3 ON table1.column1=table3.column1
the code does not seems to work, what could be wrong?
count is an aggregate function - you can't mix it with single-row functions without a group by clause. One way around this is to join on a subquery instead of directly on table3 and apply the group by there:
SELECT table1.column1, table2.column2, table1.column2, cnt
FROM table1
LEFT JOIN table2 ON table1.column1 = table2.column2
LEFT JOIN (SELECT column1, COUNT(*) AS cnt
FROM table3
GROUP BY column1) table3 ON table1.column1=table3.column1
Related
How to search three different tables with three different columns? The current command:
$sql="select t1.brand_name,t2.category_name from brand_data_add AS t1
LEFT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name
UNION select t1.brand_name,t2.category_name from brand_data_add AS t1
RIGHT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name";
SQL:
SELECT
*
FROM
(
SELECT
workouts.name,
workouts.description,
`user`.user_email
FROM
workouts
LEFT JOIN `user` ON
workouts.created_by = `user`.iduser
UNION
SELECT
workouts.name,
workouts.description,
`user`.user_email
FROM
workouts
RIGHT JOIN `user` ON
workouts.created_by = `user`.iduser) AS main_table
WHERE
user_email LIKE '%gmail%';
Explanation:
You should enclose your union query with bracket
Fetch the fields with SELECT clause
Use the WHERE clause to do the conditional filter in virtual table main_table (union of two table)
select t1.brand_name,t2.category_name, t3.? from brand_data_add AS t1
LEFT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name
LEFT JOIN t3 on t3 on t3.? = t?
UNION select t1.brand_name,t2.category_name, t3.? from brand_data_add AS t1
RIGHT JOIN category_add_data AS t2 ON t1.brand_name=t2.category_name"
RIGHT JOIN t3 on t3 on t3.? = t?
Are there significant performance considerations between using UNION versus LEFT OUTER JOIN with OR in the WHERE clause?
What is the difference between these two queries?
Is it often better to use LEFT OUTER JOINs instead of a UNION?
My reason for asking is I actually need to do an INSERT, and can't use a UNION even if I wanted to.
SELECT t.foo
FROM t
INNER JOIN t1 t1.t_id=t.id
WHERE t1.id IN (1,2,3)
UNION
SELECT t.foo
FROM t
INNER JOIN t2 t2.t_id=t.id
INNER JOIN t2a ON t2a.t2_id=t2.id
WHERE t2a.id IN (1,2,3)
UNION
SELECT t.foo
FROM t
INNER JOIN t3 t3.t_id=t.id
INNER JOIN t3a ON t3a.t3_id=t3.id
WHERE t3a.id IN (1,2,3);
SELECT DISTINCT t.foo
FROM t
LEFT OUTER JOIN t1 t1.t_id=t.id
LEFT OUTER JOIN t2 t2.t_id=t.id
LEFT OUTER JOIN t2a ON t2a.t2_id=t2.id
LEFT OUTER JOIN t3 t3.t_id=t.id
LEFT OUTER JOIN t3a ON t3a.t3_id=t3.id
WHERE t1.id IN (1,2,3) OR t2a.id IN (1,2,3) OR t3a.id IN (1,2,3);
UPDATE t
LEFT OUTER JOIN t1 t1.t_id=t.id
LEFT OUTER JOIN t2 t2.t_id=t.id
LEFT OUTER JOIN t2a ON t2a.t2_id=t2.id
LEFT OUTER JOIN t3 t3.t_id=t.id
LEFT OUTER JOIN t3a ON t3a.t3_id=t3.id
SET t.foo="bar"
WHERE t1.id IN (1,2,3) OR t2a.id IN (1,2,3) OR t3a.id IN (1,2,3);
As with many performance questions, you should test the results on your data and your systems. The union and left joins are doing very different things -- and which is better probably depends on features of your data, available indexes, and other considerations.
However, you can use the union method in update. You just need a subquery:
update t join
(select t.id, t1.foo . . .
union . . .
select t.id, t2.foo
) tt
on t.id = tt.id
set t.foo = 'foo'
where . . .;
You might also find it more efficient to use the union approach but to break the update into multiple separate update statements.
You can use UNION in inserts.
INSERT INTO `table`
SELECT * FROM
(
SELECT '1'
UNION
SELECT '2'
) x
Same goes for updates:
UPDATE `table1` t1
JOIN (
SELECT '1' as col1
UNION
SELECT '2'
) x ON x.col1 = t1.colX
SET t1.whateverColumn = "someValue"
As for performance, it's mainly down to indexes. Both can be fast, both can be slow. If you're indexing them correctly, you shouldn't see big differences between the two.
Is it possible to OR two separate INNER JOIN's so that the result set contains data from either of the two INNER JOIN's? For instance, is the following possible in MySQL.
SELECT * FROM table1
(INNER JOIN table2 ON table1.column_name=table2.column_name)
OR
(INNER JOIN table3 ON table1.column_name=table3.column_name)
No you cant do this way, one way is to use union
SELECT * FROM table1 INNER JOIN table2 ON table1.column_name=table2.column_name
union
SELECT * FROM table1 INNER JOIN table3 ON table1.column_name=table3.column_name
You can use UNION:
SELECT * FROM table1 INNER JOIN table2 ON table1.column_name=table2.column_name
UNION DISTINCT
SELECT * FROM table1 INNER JOIN table3 ON table1.column_name=table3.column_name
As described at https://dev.mysql.com/doc/refman/4.1/en/union.html, UNION combines the results of several selects.
you need use where
select * from table1
where
(table1.column_name = (select table2.column_name from table2 inner join table1.column_name as on table1.column_name = table2.column_name))
OR
(table1.column_name = (select table3.column_name from table3 inner join table1.column_name as on table1.column_name = table3.column_name))
work perfect here!
I'm trying to search a rows of table3 that have id match in a table1 OR table2 with this query
SELECT T1.*, T3.*,T2.*
FROM (
select id
from table1
where condition like '%field%') T1
inner join table3 T3
ON T3.id=T1.id
left join (
select id
from table2
where condition like '%field%') T2
ON T3.id=T2.id
If in table T1 have matches but in table2 not, the query works fine but if in table1 not have matches but have in table2 the query not show any results.
Someone can help me?
Thanks
do left join to avoid excluding rows, and add a where with the condition you need FOr readability sake,avoid right joins and jsut use proper table order
SELECT T1.*, T3.*,T2.*
FROM Table3 T3
left join (
select id
from table1
where condition like '%field%') T1
ON T3.id=T1.id
left join (
select id
from table2
where condition like '%field%') T2
ON T3.id=T2.id
where t3.id is not null or t2.id is not null
I am joining 2 tables -tbl1 and tbl2. Left join give all data from tbl1 which is in tbl2 or only on tbl1. Right join gives data from tbl2 which is don't exists in tbl1.
I want to combine both results.
What is the best way to do this so that I get all data from tbl1 and tbl2?
The only you can do that is by using UNION. MySQL doesn't support FULL JOINjust like in MSSQL.
SELECT *
FROM tbl1 t1
LEFT JOIN tbl2 t2
ON t1.col = t2.col
UNION
SELECT *
FROM tbl1 t1
RIGHT JOIN tbl2 t2
ON t1.col>= t2.<col
SEE HERE: Simulating FULL JOIN in MYSQL
By the way, UNION has optional keyword ALL,when the ALL is omitted, UNION automatically selects DISTINCT rows from the resultset.
EXAMLE:
SELECT *
FROM tableA
UNION ALL
SELECT *
FROM tableA
this can result duplicates rows
ColA ColB
==================
1 John
2 Jade
2 Jade
3 Hello
BUT if you omit the word ALL
SELECT *
FROM tableA
UNION
SELECT *
FROM tableA
this can result distinct rows only
ColA ColB
==================
1 John
2 Jade
3 Hello
What you want is FULL JOIN
LEFT JOIN + RIGHT JOIN = FULL JOIN
So try this:
SELECT * FROM tbl1
LEFT JOIN tbl2 ON tbl1.id = tbl2.id
UNION
SELECT * FROM tbl1
RIGHT JOIN tbl2 ON tbl1.id = tbl2.id
The UNION clause combines the results of two SQL queries into a single table of all matching rows.
Here's an alternative that can be easily extended if you have a full join of more than 2 tables:
SELECT t1*, t2.*
FROM
( SELECT col
FROM tbl1
UNION
SELECT col
FROM tbl2
) AS d
LEFT JOIN tbl1 AS t1
ON t1.col = d.col
LEFT JOIN tbl2 AS t2
ON t2.col = d.col ;
you have to use FULL OUTER JOIN, But mysql doesnt support it.. You could do this for getting the result:
SELECT *
FROM tbl1 t1 LEFT JOIN tbl2 t2
ON t1.<col> = t2.<col>
UNION
SELECT *
FROM tbl1 t1 RIGHT JOIN tbl2 t2
ON t1.<col>= t2.<col>