I have two tables with one-to-one relations like: people has one to one relation with status table
**people table**
ID Name Status
1 Mick 1
2 Rohit null
3 Virat 1
4 Viru null
5 Gilly 2
6 Shann null
7 Mitch 3
**status table**
ID Status
1 started
2 not-started
3 pending
4 waiting
I need to get the people with status "null" and "started"(from ex: Mick, Rohit, Virat, Viru, Shann).
I tried with SQL query
select p.id, p.name
from people p
inner join status s on s.id = p.status
where (s.name IS NULL OR s.name = 'started')
this is giving only names which have a relation I mean "Mick, Virat" (skips nulls).
I don't know what I am missing here. thanks in advance
In order to keep people records where no status matches you need an OUTER join. In this case, a LEFT OUTER JOIN, which is often shortened to just LEFT JOIN:
select p.id, p.name
from people p
left join status s on s.id = p.status
where coalesce(s.name, 'started') = 'started'
Related
I have 2 tables, this is my fiddle http://sqlfiddle.com/#!9/da5e4e/3
so basically i have 2 tables called personal and interview_score with personal.id = interview_score.personal_id.
assume this is my personal table
id name
1 John Doe
2 Nian
3 Rijali
and this is my interview_score table
id personal_id aspect_id
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
on this case, i just want to count how many personal_id in my interview_score table with this query
SELECT COUNT(i.id) as interviewed FROM personal p LEFT JOIN interview_score i ON i.personal_id = p.id GROUP BY i.personal_id;
but it returns just like this
interviewed
0
3
2
meanwhile, my expected result is just like this
interviewed
2
because on that table there are 2 personal_id based on that condition.
where my wrong at?
You can use join instead of left join also you need to group by p.id
SELECT COUNT(i.id) as interviewed FROM personal p JOIN interview_score i ON i.personal_id = p.id GROUP BY p.id;
from the above query you can get the count
To get count for a particular person
SELECT COUNT(i.id) as interviewed FROM personal p JOIN interview_score i ON i.personal_id = p.id and p.id=1 GROUP BY p.id;
i've experienced something... weird? using an aggregate function WITHOUT group by statement (yes, i know i sould). I'm using mysql 5.5 in this moment.
I've use some example tables with the same structure as in my real situation, so example may be extrange, sorry.
Let's explain.
I have three tables with some referencial integrity:
As you can imagine: both, parent, child and person, are FK from Persons table id.
- Persons -
id name
1 Anna
2 Ben
3 Charly
4 Dennis
5 Emma
6 Fiona
- Relationships -
parent child
1 3
1 4
2 5
- Log -
person date
1 2020-05-05
Anna has two childs, Charly and Dennis
Ben has one, Emma
Fiona hasn't
Only Anna has an entry on log table
Let's party.
Find children id 3 name ONLY if number 6 is his parent (looking for Charly if is Fiona's son)
select P.name, R.child, R.parent
from Persons P
join Relationships R on P.id = R.child
left join Log L on L.person = P.id
where R.parent = 1
and R.child = 3
No result shown, ok, that's what i expected because as we can see, there's no row that matches condition.
Adding an aggregate function and group by shows the same 0 results.
select P.name, R.child, R.parent, count(L.person) as N_Entries
from Persons P
join Relationships R on P.id = R.child
left join Log on L.person = P.id
where R.parent = 1
and R.child = 3
group by P.id
BUT
if i remove the group by condition i expect the same result
if there're no result, then grouping should be unnecesary.
select P.name, R.child, R.parent, count(L.person) as N_Entries
from Persons P
join Relationships R on P.id = R.child
left join Log on L.person = P.id
where R.parent = 1
and R.child = 3
name child parent N_Entries
Charly null null 0
Why does it returns something?
Thank you and sorry about my bad english.
I need help on how to set up an QUERY that will result in different outputs based on the results that it achieves on the way and I'm completely stuck!
I'll give you some more details, first of all, here's my current database setup:
#USERS
id username etc..
1 alex123
2 bonnie9
3 clyde_x
#COURSES
id course_name visibility etc..
1 Name 1 1
2 Name 2 0
3 Name 3 1
#COURSE_ENROLMENT
id user_id course_id
1 1 1
2 1 2
3 3 1
The scenario is as following..
I need to list the courses to the users that are enrolled to it, which is quite easily done by something like:
SELECT
*
FROM COURSES C
JOIN COURSE_ENROLMENT E ON C.ID = E.COURSE_ID
However. If the course visibility (Database: Course, Column: visibility) is set to be visible for everyone = 1, then it will override or just ignore the enrolment and show the course to all users anyway.
How can I achieve something like this? I've tried to research CASE but can't really figure out how to proceed. Greatest thanks for any help!
To answer this you're going to need to LEFT JOIN your COURSE and COURSE_ENROLLMENT tables using an OR, so either the person is enrolled in the subject OR the visibility is set to 0.
If you change your JOIN to a LEFT JOIN, that will give you all courses, regardless of whether someone has enrolled in them or not. You can then filter out the courses which have not had anyone enrolled and are not visible by checking for visibility = 1:
SELECT *
FROM Courses C
LEFT JOIN Course_Enrolment E ON C.id = E.course_id
WHERE C.visibility = 1 OR E.id IS NOT NULL
Output:
id course_name visibility id user_id course_id
1 Name 1 1 1 1 1
2 Name 2 0 2 1 2
1 Name 1 1 3 3 1
3 Name 3 1 null null null
Demo on dbfiddle
If visibility=1 means that the course will be returned for all users, then you can do it with a cross join for that case and UNION ALL:
select c.course_name, u.username
from users u
inner join course_enrolment e on e.user_id = u.id
inner join (
select * from courses where visibility = 0
) c on c.id = e.course_id
union all
select c.course_name, u.username
from users u
cross join (
select * from courses where visibility = 1
) c
order by course_name, username
MEMBERS_TABLE
member_id
---------------------------------------------
1
ACCOUNTS_TABLE
account_id member_id
---------------------------------------------
1 1
INVESTMENTS_TABLE
investment_id account_id
---------------------------------------------
1 1
2 1
FUNDS_TABLE
fund_id investment_id
---------------------------------------------
1 1
2 2
This is my current query:
SELECT
m.member_id,
a.account_id,
i.investment_id,
f.fund_id,
COUNT(a.account_id) AS member_accounts_total,
COUNT(i.investment_id) AS member_investments_total,
COUNT(f.fund_id) AS member_funds_total
FROM members AS m
LEFT JOIN accounts AS a ON m.member_id = a.member_id
LEFT JOIN investments AS i ON a.account_id = i.account_id
LEFT JOIN funds AS f ON f.fund_id = i.fund_id
I would like to see the following results:
member_accounts_total: 1
member_investments_total: 2
member_funds_total: 2
Instead, I am getting these results:
member_accounts_total: 2
member_investments_total: 2
member_funds_total: 2
I really don't want to write multiple queries for this.
Just need to change
COUNT(a.account_id) AS member_accounts_total,
to
COUNT( distinct a.account_id) AS member_accounts_total,
The reason you're getting 2 is because the left join on accounts to investments results in 2 records. To get a distinct count of members you need to add well... distinct.
Note you may have problems with the other totals as well (Distinct may be needed there as well in the long run...) say if a member had multiple accounts. you may get odd counts as well (if each account had the same investment... would you want to see the count only once or twice?
I have 2 tables as below:
1.Products
product_id, name
1 Books A
2 Books B
3 Books C
4 Books D
5 Books E
2.liked_items
user_id, product_id
1 4
1 3
1 1
I want to query (sql) to retrieve result as below.
Can I do in same single query?
product_id, user_id
1 1
2 0
3 1
4 1
5 0
Hi, this first time i'm posting here.
Hope anyone can help me. Thank you
SELECT Products.product_id,liked_items.product_id,liked_items.user_id
FROM Products
LEFT JOIN liked_items
ON Products.product_id=liked_items.product_id
Try this one,
SELECT a.product_ID,
COALESCE(b.user_id,0) `user_id`
FROM products a
LEFT JOIN liked_items b
ON a.product_ID = b.product_ID
Sometimes liked_items.user_id can be possibly NULL so instead of displaying NULL in the result list, it can be changed using COALESCE. COALESCE is a function that can change NULL value into your desired value.
Click For Demonstration
SELECT
Products.product_id AS product_id,
IFNULL(liked_items.user_id,0) AS user_id
FROM Products
LEFT JOIN liked_items ON liked_items.product_id=Products.product_id
If you're using MS SQL Server you can use IsNull like so:
SELECT p.product_id, IsNull(li.user_id, 0)
FROM products p
LEFT JOIN liked_items li
ON (p.product_id = li.product_id);
If not, Joao or John's answer will do just fine.