I tried to count how many new tuples are in a subset of t2 as compared to t1 by
SELECT
COUNT(t2.id)
FROM (
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
LEFT OUTER JOIN
t1
ON
t.id=t1.id
)
WHERE
t1.id IS NULL;
The subset is defined by
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
But the above program doesn't seem to work, issuing errors.
There is no need to enclose the FROM clause in (). You are referencing t2.id in your aggregate COUNT(), but your SELECT list will only produce t.id from the subquery that encapsulates t2. This version addresses the source of your errors:
SELECT
COUNT(t.id) AS idcount
FROM
(SELECT id, col1 FROM t2 WHERE col2=0 AND col3=0) AS t
LEFT OUTER JOIN t1 ON t.id = t1.id
WHERE t1.id IS NULL
However:
Since your subquery is actually pretty simple, I believe it isn't necessary at all. The whole thing can be done with a LEFT JOIN:
SELECT
/* The equivalent of COUNT(*) in this context */
COUNT(t2.id) AS idcount
FROM
t2
LEFT OUTER JOIN t1 ON t2.id = t1.id
WHERE
t1.id IS NULL
AND (t2.col2 = 0 AND t2.col3 = 0)
are you sure you don't want to do COUNT(t.id)? t2 is in a subquery and is not available to the main query only t and t1 are available.
The problem is the alias. You have:
select count(t2.id)
But, t2 is defined in the subquery, so it is out of scope.
You want:
select count(t.id)
Related
I basically want to join the result of two INNER JOINs.
On this scheme I want to get the three arrows results combined.
I've tried INNER / LEFT combinations but it doesn't do the trick.
I think a nested request could be the solution but how ?
Thanks
The answer was actually simple : UNION
SELECT t1.*
FROM
(SELECT t1.*
FROM table1 t1 JOIN table2 t2 ON t2.id = i.client_id
UNION
SELECT t1.*
FROM t1 t1 JOIN table3 t3 ON t1.id = t3.client_id) as q1
;
I'd use logic to express the condition T1.id exists in T2 or T3 more directly, and certainly avoid use of DISTINCT or UNION.
Options could be to use EXISTS directly (As this is immure to the possibility of duplication cause by 1:many joins)...
SELECT
t1.*
FROM
table1 t1
WHERE
EXISTS (SELECT * FROM table2 t2 WHERE t2.t1_id = t1.id)
OR
EXISTS (SELECT * FROM table3 t3 WHERE t3.t1_id = t1.id)
Or to LEFT JOIN twice and then exclude unwanted rows. (This assumes that the joins are never 1:many, which would introduce duplication, and the unwanted need for a DISTINCT.)
SELECT
t1.*
FROM
table1 t1
LEFT JOIN
table2 t2
ON t1.id = t2.t1_id
LEFT JOIN
table3 t3
ON t1.id = t3.t1_id
WHERE
t2.t1_id IS NOT NULL
OR
t3.t1_id IS NOT NULL
I have 2 tables, one is table1
and another is table 2
I want the result by a query, like
I have tried select id from table2 order by (select id from table1); but it is giving error.
You can join and sort. But you need a column that defines the ordering of the rows in table1. Let me assume that you have such column, and that is is called ordering_id.
select t2.*
from table2 t2
inner join table1 t1 on t1.id = t2.id
order by t1.ordering_id
You can even use a subquery in the order by clause:
select *
from table2 t2
order by (select t1.ordering_id from table1 t1 where t1.id = t2.id)
Join the two tables and then order the result.But for that you need to have some column for ordering and this does not seems to be the case. Syntax you are using for ordering will not work.
SELECT A.ID, B.NAME FROM TABLE1 A INNER JOIN TABLE2 B
ON(A.ID = B.ID) ORDER BY A.ID DESC
finally got the answer
select t2.*
from table2 t2
inner join table1 t1 on t1.id = t2.id;
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
WHERE ids IN (t1.values)
) as t2
WHERE t1.id = 20;
I get an error, that t1.values inside the subquery is unknown column.
You need to rewrite your query and take inne where to join condition:
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount
FROM database2.table
) as t2 ON t2.ids = t1.values
WHERE t1.id = 20;
Also, you don't use amount column, so what is the point of join?
Another issue, you don't have any join condition defined.
I think you need to read about joins in SQL first :)
It seems you are trying to join database2.table to your t1 based on t1.values list.
I added group by IDs in t2 since your using aggregation function. Then, not sure what's the purpose of your sum(amount)
SELECT t1.name as r_name, t1.values as r_values
FROM table as t1
JOIN (
SELECT SUM(amount) as amount, ids
FROM database2.table
GROUP BY ids
) as t2 on t2.ids IN (t1.values)
WHERE t1.id = 20;
Is is possible to simplify this UNION to avoid the near redundancy of the queries being unioned? As seen here, both queries are similar. They just join on a different column in table2. The reason i use Union, instead of just Inner Joining 2x in the same query is because the results must be in 1 column by virtue of the fact that this queries is used as a subquery.
SELECT t1.id as id
FROM table1 g
INNER JOIN table2 t1 on g.t_id = t1.id
WHERE g.id=1
UNION
SELECT t2.id as id2
FROM table1 g
INNER JOIN table2 t2 on g.t2_id = t2.id
WHERE g.id=1
I don't see why this couldn't be treated as a simple inner join that can be satisfied by a match in either of two predicates. I've removed the original table aliases of t1, t2, and g for the sake of clarity. Since I don't know if the query could produce duplicate rows, I used DISTINCT in order to collapse duplicate rows in the same manner that the UNION did in the original query.
SELECT DISTINCT table2.id
FROM table1
INNER JOIN table2
ON ( table1.t_id = table2.id OR table1.t2_id = table2.id )
WHERE table1.id = 1
;
It is possible to do with two joins, and the IFNULL() function:
SELECT IFNULL (t1.id, t2.id) as id
FROM table1 g
INNER JOIN table2 t1 on g.t_id = t1.id
INNER JOIN table2 t2 on g.t2_id = t2.id
WHERE g.id=1
You might find this simpler:
select distinct t.id
from table2 t
where t.id in (select g.t_id from table1 g) or
t.id in (select g.t2_id from table1 g)
However, the performance would be awful on MySQL. You can also do:
select distinct t.id
from table2 t
where exists (select 1 from table1 g where g.t_id = t.id or g.t2_id = t.id)
The second version should work better in MySQL.
If I have
SELECT * FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.id = t2.id
WHERE t1.user='bob';
Does the WHERE clause run after the two tables are JOINED?
How do I make it so it runs prior to the JOIN?
The where clause will be executed before the join so that it doesn't join unnecessary records. So your code is fine the way it is.
Change the WHERE to another JOIN condition
LEFT JOIN Table2 t2 on t1.id = t2.id AND t1.user='bob'
In my experience in a left join you cannot exclude records in the 'left' (t1) table in the ON-statement since - by definition - all t1 records will be included. The where statement does work as it will be applied to the result of the join afterwards.
I do not exactly know what you want to achieve but most probably an inner join suits your needs as well and then you can add the t1.user='bob' condition to the ON-statement.
But if Mosty Mostacho is correct, the location (WHERE vs ON) of the condition is not relevant for speed of execution.
You should just add t1.user='bob' condition to ON clause before other condition and it will be evaluated first:
SELECT * FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.user='bob' AND t1.id = t2.id;
What you may use is table expression after FROM like this:
SELECT *
FROM (SELECT
id
FROM Table1
WHERE user = 'bob') AS t1
LEFT JOIN Table2 t2
ON t1.id = t2.id
you can do
SELECT *
FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.id=t2.id AND t1.user='bob';
RIGHT JOIN was the solution:
SELECT cars.manufacturer, cars.year FROM cars
RIGHT JOIN (SELECT m.manufacturer FROM cars AS m ORDER BY m.year DESC LIMIT 3) subq
ON cars.manufacturer=subq.manufacturer
Haven't put it through the full rigors yet, but seems to work.