need a help in left join query in mysql - mysql

table1:
name | map_id | reg_id
abc | 1 | 5
pqr | 2 | 5
xyz | 3 | 5
table2:
map_id | map_name | is_deleted
1 | map1 | 0
2 | map2 | 0
my sql query :
SELECT *
FROM table1 t1
LEFT JOIN table2 t2
ON t1.map_id = t2.map_id
WHERE t1.reg_id = 5
AND t2.is_deleted = 0
what the above query does is stops me from retrieving record with map_id = 3 in table1.
how can i achieve this as well as 'is_deleted check' if the record exists in table2.
thanks in advance.

You need to move the is_deleted check to the JOIN:
select t1.name, t1.map_id, t1.reg_id, -- replace select * with columns
t2.map_name, t2.is_deleted
from table1 t1
left join table2 t2
on t1.map_id = t2.map_id
and t2.is_deleted = 0
WHERE t1.reg_id = 5;
See SQL Fiddle with Demo. Your current query is causing the LEFT JOIN to act like an INNER JOIN because you have the is_deleted as a part of the WHERE clause. If you move that to the JOIN, then you will return the rows from table2 that have is_deleted=0 and you will still return all rows from table1 where reg_id=5.

Related

Compare data for 2 tables

i have 2 tables A and B like below
Table A
+---------+--------+
| query | status |
+---------+--------+
| number1 | solved |
+---------+--------+
table B
+----+---------+---------+
| id | query | status |
+----+---------+---------+
| 1 | number1 | started |
| 2 | number1 | working |
| 3 | number1 | solved |
+----+---------+---------+
how do i check whether the latest status of table B is equal to status of Table A
i have tried first getting latest status for table 2 but i am unable to get so
select number ,max(status),max(id)
from Table B
group by number
order by max(id) asc
Here is a simple solution relying on sorting by ID and getting only first row in a sub-query. It will only returns rows that has a match between the two tables.
SELECT a.*
FROM tableA a
JOIN (SELECT query, status
FROM tableB
ORDER BY ID desc
LIMIT 1) b ON a.query = b.query AND a.status = b.status
use join and subquery
select a.* from
tablea a join
(
select * from table_name t1
where id =( select max(id) from table_name t2 where t1.query=t2.query)
) b join on a.query=b.query and a.status=b.status
select *
from A a
inner join B b on b.query = a.query
inner join
(select max(id) id, query
from B
group by query) gq on gq.id = b.id and gq.query = b.query
where a.status = b.status

Count records in one table where there are no records in linked table matching certain criteria

I have 2 tables:
T1:
id | name
------ | ------
1 | Bob
2 | John
3 | Joe
T2:
id | T1_id | type
------ | ------ | ------
1 | 1 | call
2 | 1 | email
3 | 1 | fax
4 | 2 | call
5 | 2 | email
6 | 2 | fax
7 | 3 | call
8 | 3 | email
I want to count the number of records in T1 which do not have a record in T2 with a type of 'fax'.
So the answer in this case would be 1 (3|Joe)
Currently I have:
SELECT count(*)
FROM `T1`
JOIN `T2` on `T1`.`id` = `T2`.`T1_id`
WHERE `T2`.`type` != 'fax'
But this is obviously counting all the records which are not 'fax'. I just cant get the logic in my head.
Any help would be appreciated!
A subquery is unnecessary:
SELECT COUNT(DISTINCT t1.id)
FROM t1
LEFT
JOIN t2
ON t2.t1_id = t1.id
AND t2.type = 'fax'
WHERE t2.id IS NULL;
select count(*)
from
(
SELECT t1.id
FROM T1
LEFT JOIN T2 on T1.id = T2.T1_id
GROUP BY t1.id
HAVING sum(T2.type = 'fax') = 0
) tmp
The answers given by Strawberry and juergen d are correct, but for completeness, here's another example using NOT EXISTS. All the queries will have different execution plans, so depending on your data in T1 and T2 YMMV:
SELECT COUNT(*)
FROM `T1`
WHERE NOT EXISTS (
SELECT *
FROM `T2`
WHERE `T2`.`T1_id` = `T1`.`id`
AND `T2`.`type` = 'fax'
)

SQL select 2 tables but not ommit blank results

I have to do a select from 3 trables.
table1- idc,title,description..
table2- idc,filename,filepath,tabel1FK
table3- idc,table1FK,tabel2FK
I need a select from table1 and table2 and count unique ocurrences of table1 in table3
the select must be something like this
TB1 | TB2 | COUNT ON TB3
a | aa | 1
b | | 4
c | cc | 3
d | | 0
e | | 3
I think you just want left join and group by:
select tb1.idc, tb2.idc, count(tb3.idc)
from tb1 left join
tb2
on tb2.table1FK = tb1.idc left join
tb3
on tb3.table1FK = tb1.idc and tb3.tabel2FK = tb2.idc
group by tb1.idc, tb2.idc;

MySQL select multiple row on table 2 with two differents Id from table 1 result in one row as two differents fields

Is it possible in only one MySQL query to get the desired result (below) returned into one row ?
Where id=1 in Table 1
Table 1
|------|----------|----------|
| id | refIdOne | refIdTwo |
|------|----------|-----------
| 1 | 1 | 2 |
|------|----------|-----------
Columns "refIdOne" & "refIdTwo" refer Table 2 "id" column
Table 2
|------|------------------|
| id | text |
|------|------------------|
| 1 | cheese |
| 2 | made with milk |
|------|------------------|
Desired result returned in ONE ROW with custom AS columns named "subject" and "description" :
|----------|-----------------|
| subject | description |
|----------|-----------------|
| cheese | made with milk |
? Many thanks for help
* EDIT : Answer is *
select t21.text as subject, t22.text as description
from Table1 as t1
join Table2 as t21 on t1.refidone = t21.id
join Table2 as t22 on t1.refidtwo = t22.id
where t1.id = 1
Table2 has to joined twice to Table1.
select t21.text as subject, t22.text as description
from table1 t1
join table2 t21 on t1.refidone = t21.id
join table2 t22 on t1.refidtwo = t22.id
You need to perform Self join. Join Table2.ID twice with Table1.refIdOne and Table1.refIdTwo
select t2.text as subject, t3.text as description
from Table1 t1
Left join Table2 t2 on t1.refIdOne = t2.id
Left join Table2 t3 on t1.refIdTwo = t2.id
without joins
SELECT
(SELECT text FROM Table2 WHERE id = (SELECT refIdOne FROM Table1 WHERE id = 1) ) AS name,
(SELECT text FROM Table2 WHERE id = (SELECT refIdTwo FROM Table1 WHERE id = 1) ) AS description

update rows after left join

I'm looking for a way to update some values in a table if they were used in a left join.
I have two tables:
table1:
id | name | age | job
1 | john | 31 |
2 | eric | 25 |
table2:
id | job | inserted
1 | lawyer | 0
2 | dentist | 1
3 | cop | 0
Then I run the query:
UPDATE table1
LEFT JOIN
table2
ON table1.id = table2.id
SET table1.job = `table2.job`
WHERE table2.inserted = 0
But I want to update the rows from table2 that were used in the update so they have inserted = 1. This for two reasons 1) to speed up the join and 2) so I can check which rows of table2 were not used. (The inserts in table2 happen before table1, but the ids in table2 should always be present in table1 if all cron jobs run okay.)
You shouldn't be using a LEFT JOIN, since you only want to update rows in table1 that have a matching row in table2. Try:
UPDATE table1 AS t1
JOIN table2 AS t2 ON t1.id = t2.id
SET t1.job = t2.job, t2.inserted = 1
WHERE t2.inserted = 0
DEMO