Mysql left join with condition in right table - mysql

I have been trying to solve this issue for a while, hope anyone help me. I am having two table, the first table is
Table Name : OnlineTest
OnlineTestId category subcategory
1 English Spelling
2 English Grammar
3 English Antonyms
4 English Synonyms
The second table is
Table Name : UserStatus
Id userId status onlineTestId
1 1 Finished 1
2 1 Not Finished 2
3 2 Not Finished 1
4 2 Finished 3
5 3 Not Finished 4
Result
OnlineTestId userId status
1 1 Finished
2 1 Not Finished
3 null null
4 null null
I have tried this query,
select c.onlinetestid, d.userid, d.status from onlinetest c left join userstatus d on d.onlinetestid = c.onlinetestid
where c.category = 'English' and d.userid = 1;
But this query is bring the first two row of the result and not the last two, in which the userId and status are null.
How to bring the above result?

Place the d.userid = 1 predicate in the ON clause:
select c.onlinetestid, d.userid, d.status
from onlinetest c
left join userstatus d on d.onlinetestid = c.onlinetestid and d.userid = 1
where c.category = 'English'
This will return all rows from onlinetest, having columns of userstatus filled with nulls where predicate d.userid = 1 fails.

You can also use left outer Join as below :
SELECT c.OnlineTestId, d.userId, d.status
FROM OnlineTest AS c LEFT OUTER JOIN
UserStatus AS d ON d.onlineTestId = c.OnlineTestId AND d.userId = 1
WHERE (c.category = 'English')

Related

Issue getting while fetching data using joins

I have four table and structure as below :
1)Budget
id Budget_name
1 test1
2 test2
3 test3
2)Yearly Budget
id amount_yearly budgetid
1 1000 1
2 2000 2
3 5000 3
ri_spent
id Spent_amount budgetid
1 100 2
2 100 2
3 200 3
4)FI_spent
id Spent_amount budgetid
1 100 2
2 100 3
3 200 3
i want to fetch data accourding to or based on first budget table id
below is the query i was trying:
select d.centers as Cost_Center,
ud.BUDGET_ANNUAL_AMOUNT as Annual_Budget,
l.LEAD_ID as Lead_Id,
l.AMOUNT as Lead_Amount,
f.FINANCEADD_ID as Finance_Id,
f.AMOUNT as Finance_Amount
from Cost_centers as d
inner join ANNUAL_BUDGET_BUDGET_CENTER as ud on d.id = ud.BUDGET_ID
inner join RI_DETAILS as l on l.COST_CENTER = d.id
inner join F_RI_DETAILS as f on f.COST_CENTER = d.id
ORDER BY d.id DESC
I want output of the following way:
Id Name ri_id FI_ID RI_Spent_Amount FI_Spent_Amount Annual_Buget
1 test1 1000
2 test2 1 1 100 200 1000
2 test2 2 100 2000
3 test3 3 2 300 100 2000
3 test3 3 200 2000
Any way if possible then please help me.
I want to minus annual budget with spent_amount later.
If possible then help me .
Please Try This Query ,
select b.id ,
b.Budget_name,
y.id,
y.amount_yearly,
r.id,
r.ri_spent,
f.id,
f.Spent_amount
from Budget b
INNER JOIN Yearly_Budget y on y.budgetid =b.id
INNER JOIN ri_spent r on r.budgetid =b.id
INNER JOIN FI_spent f on f.budgetid =b.id
ORDER BY b.id DESC
Could you please use left join instead of inner join. Requirement and sql arent matching so i may be little off. But you can get the idea.
select d.centers as Cost_Center,
ud.BUDGET_ANNUAL_AMOUNT as Annual_Budget,
l.LEAD_ID as Lead_Id,
l.AMOUNT as Lead_Amount,
f.FINANCEADD_ID as Finance_Id,
f.AMOUNT as Finance_Amount
from Cost_centers as d -- I assume this is the budget table
left outer join ANNUAL_BUDGET_BUDGET_CENTER as ud on d.id = ud.BUDGET_ID
left outer join RI_DETAILS as l on l.COST_CENTER = d.id
left outer join
(select sum(FINANCEADD_ID) FINANCEADD_ID,sum(AMOUNT) AMOUNT,id from
F_RI_DETAILS group by id) as f
on f.COST_CENTER = l.id
ORDER BY d.id DESC

Mysql query for finding followers and following

Here are the two tables:
1.user
user_id | full_name | username
1 A A_1
2 B B_2
3 C C_3
4 D D_4
5 E E_5
2.user_follower
user_id | follower_id | follow_dtm
2 4 2018-10-09 10:10:10
2 3 2018-01-09 11:10:10
1 5 2018-11-09 07:10:10
4 2 2018-10-09 06:10:10
4 5 2018-10-09 00:10:10
Find follower of user: 2
Output should be:
user_id: 4 fullname: D username: D_4 f_total_flwr: 2 (num of flwr of id-4) following: yes
user_id: 3 fullname: C username: C_3 f_total_flwr: 0 (num of flwr of id-3) following: no
I need a mysql query to find all the followers of a particular user with detail information of the followers from user table and need to know the number of followers each follower has and i also need to if the the particular user also following the follower. Here's what I have tried:
SELECT u.user_id
, u.full_name
, u.username
, COUNT(DISTINCT uf.follower_id) f_total_flwr
, case when b.user_id is null then 'no' else 'yes' end following
FROM user_follower
JOIN user u
ON user_follower.follower_id = u.user_id
LEFT
JOIN user_follower uf
ON u.user_id = uf.user_id
LEFT
JOIN user_follower b
ON b.user_id = user_follower.follower_id
and b.user_id = u.user_id
WHERE user_follower.user_id=2
GROUP
BY u.user_id
ORDER
BY uf.follow_dtm DESC
LIMIT 30
I know I'm getting close ;). The problem is, I'm getting following with a yes value even though the user is not following back.Here is another weird thing - not all but some of them showing yes which should be no .Thanks!
Try this:
select u2.*,b.fcount, case when uf3.user_id is null then 'no' else 'yes' end as connected from user u2 inner join
(
select u.user_id,count(distinct(uf2.follower_id)) fcount
from user u
inner join user_follower uf1 on u.user_id=uf1.follower_id and uf1.user_id=1
left join user_follower uf2 on uf2.user_id=uf1.follower_id
group by u.user_id
) b on u2.user_id=b.user_id
left join user_follower uf3 on u2.user_id=uf3.user_id and uf3.follower_id=1
I tried it using the following data sets:
USER
1,a,abcd
2,b,bcde
3,c,cdef
user_follower
1,2,10
1,3,11
2,3,10
3,1,13
And got the expected result:
2,b,bcde,1,no
3,c,cdef,1,yes

count for different column in union and displaying in same row

I am trying to get a count(*) for different column from a different table using union.
//tbl_churidar
order_id order_no_first order_no
--------------------------------------
1 C 1000
2 C 1001
3 C 1002
//tbl_anarkali
order_id order_no_first order_no
--------------------------------------
1 A 1003
2 A 1004
3 A 1005
//tbl_assign
assign_id order_id order_no_first
---------------------------------------
1 1 C
2 1 A
3 2 C
4 3 C
5 2 A
6 3 A
//tbl_unit_status
status_id assign_id status_status stitching_worker
-----------------------------------------------------------
1 1 Stitch AA
2 2 QC {null}
3 3 Stitch BB
4 4 Stitch BB
5 5 Stitch AA
6 6 Stitch CC
from the table tbl_unit_status where status_status = Stitch should INNER JOIN with other two table and get the total count of churidar and anarkali each stitching_worker taken.
the required output is,
churidar anarkali stitching_worker
----------------------------------------
1 1 AA
2 0 BB
0 1 CC
I have tried to get the above output but got stuck. Below is my code,
SELECT churidar, anarkali, stitching_worker
FROM ((
SELECT count(*) AS churidar, NULL AS anarkali,
us.stitching_worker
FROM tbl_unit_status us
INNER JOIN tbl_assign a ON a.assign_id = us.assign_id
INNER JOIN tbl_churidar o ON
(o.order_id = a.order_id AND
o.order_no_first = a.order_no_first)
INNER JOIN tbl_contacts c ON c.contacts_id = o.contacts_id
LEFT JOIN tbl_title t ON t.title_id = c.title_id
WHERE us.status_status = "Stitch" AND
o.order_no_first = "C"
GROUP BY us.stitching_worker
)
UNION (
SELECT NULL AS churidar, count(*) AS anarkali,
us.stitching_worker
FROM tbl_unit_status us
INNER JOIN tbl_assign a ON a.assign_id = us.assign_id
INNER JOIN tbl_anarkali o ON (
o.order_id = a.order_id AND
o.order_no_first = a.order_no_first)
INNER JOIN tbl_contacts c ON c.contacts_id = o.contacts_id
LEFT JOIN tbl_title t ON t.title_id = c.title_id
WHERE us.status_status = "Stitch" AND
o.order_no_first = "A"
GROUP BY us.stitching_worker
)
) AS T1
the output for the above code is,
churidar anarkali stitching_worker
----------------------------------------
1 0 AA
{null} 1 AA
2 0 BB
0 1 CC
how to get the required output. I have tried a lot. Help me find the answer. Thankyou.
If I understand correctly (which I may not), you don't need the first two tables. You can get the information you need from tbl_assign and just use aggregation:
select us.stitching_working,
sum(a.order_no_first = 'C') as churidar,
sum(a.order_no_first = 'A') as anarkali
from tbl_unit_status us join
tbl_assign a
on us.assign_id = a.assign_id
where us.status_status = 'Stitch'
group by us.stitching_working;

MySQL Select Distinct with Left Join?

I am trying to get a list of company_id's that have no company-level notes. The company may, however, have location-level notes.
company
-------------------------
company_id name deleted
1 Foo 0
2 Bar 0
3 Baz 0
location
-----------------------
location_id company_id
6 1
7 2
8 3
note
-----------------------------------------
note_id company_id location_id deleted
10 2 6 0 // location-level note
11 1 7 0 // location-level note
12 null 8 0 // location-level note
13 2 null 0 // company-level note
I would want my result table to be this:
company_id name
1 Foo
3 Baz
Update
Foo/company_id = 1 does not have a company-level note because the note also has a location_id, which makes it a location-level note. Company-level notes are notes that only link to a company (and not a location).
End of Update
I've tried doing something like this, but it returns an empty set, so I'm not sure if it's working and there aren't any companies without company-level notes or if I'm doing something wrong.
SELECT DISTINCT
c.company_id,
c.name
FROM company AS c
LEFT JOIN note AS n
ON c.company_id = n.company_id
WHERE
c.deleted = 0 AND
n.deleted = 0 AND
n.location_id IS NOT NULL AND
n.location_id != 0 AND
c.company_id = (SELECT MAX(company_id) FROM company)
Revised Accepted Answer by Mike
SELECT
company_id,
name
FROM company
WHERE
deleted = 0 AND
company_id NOT IN (
SELECT DISTINCT
c.company_id
FROM company AS c
INNER JOIN note AS n
ON c.company_id = n.company_id
WHERE (
n.deleted = 0 AND
(n.location_id IS NULL OR
n.location_id = 0)
)
);
The easiest way to think about this is to first find the all the companies that have company level notes, which you can do with
select distinct c.company_id
from company c
inner join notes n
on c.company_id = n.company_id
where n.location_id is null;
Then simply remove these companies from the company select:
select company_id,
name
from company
where company_id not in (select distinct c.company_id
from company c
inner join notes n
on c.company_id = n.company_id
where n.location_id is null);
*Updated to use inner join instead of comma-separated join.
SELECT DISTINCT c.*
FROM company c
LEFT
JOIN note n
ON n.company_id = c.company_id
AND n.location_id IS NULL
WHERE n.note_id IS NULL;

getting count on same column using inner join

I have a table like this, in which I need to set the male and female counts for the primary key id:
summaryTable:
id femaleCount maleCount
-----------------------------
s1 ? ?
s2 ? ?
... and so on
There is a detail table as below, that has the users corresponding to each id of summaryTable:
id parentId userId
--------------------------
1 s1 u1
2 s1 u2
3 s2 u2
4 s2 u2
...and so on
The third is the user table like this:
userTable:
userId gender
-------------
u1 M
u2 F
u3 F
..and so on
I have to update the summary table with the counts of male and female. So as per the above, for id=s1, femaleCount should be set to 1 , maleCOunt=1
For id=s2, femaleCOunt should get set to 2 and maleCount=0
Is this possible to do using an UPDATE query in MySQL?
I tried the following, but this returns the sum of occurences of a user i.e. if u1 occurs 2 times for p1(say), then it will return count as 2 and not 1:
SELECT
d.parentId,
SUM(gender = 'F') AS 'F#',
sum(gender = 'M') as 'M#'
FROM detailsTable as d
JOIN userTable as c on c.userId = d.userId
GROUP BY d.parentId;
Also tried as below, but it gave an error:
select d.parentId,
count(case when c.gender='M' then 1 end) as male_cnt,
count(case when c.gender='F' then 1 end) as female_cnt,
from detailsTable d, userTable c where d.userId=c.userId group by d.parentId, d.userId ;
Further, my problem doesnt just end at the select, I need to get the values and then update these in the summary table too.
I might be rusty on the syntax for MySql but I believe this does what you need. The CASE/SUM is effectively a pivot to get the counts, then you can update the table as normal.
UPDATE summaryTable AS st
INNER JOIN ( SELECT parentId
,SUM(CASE WHEN gender = 'f' THEN 1
ELSE 0
END) femaleCount
,SUM(CASE WHEN gender = 'm' THEN 1
ELSE 0
END) maleCount
FROM userTable d
INNER JOIN (SELECT DISTINCT parentId, userId FROM detail) ut ON d.userId = ut.userId
GROUP BY parentId
) AS c ON c.parentId = st.parentId
SET femaleCount = c.femaleCount
,maleCount = c.maleCount