SQL to check if the value is not present in table - mysql

I am working on following SQL:
select *
from `STUDENTLOC` l,
STUDENT s,
ATTENDANCE a
where l.STUDENTID = s.ID
and l.LOCID = 3
Now I need to make sure that the values are not already present in ATTENDANCE table. It has following structure:
ID StudentID ScheduleID
1 6 6
2 3 3
It is a simple list where I need to display list of students whose record have not been added in ATTENDANCE table.

You can use not exists:
select *
from `STUDENTLOC` l
join STUDENT s on l.STUDENTID = s.ID
where not exists (
select 1
from ATTENDANCE a
where a.STUDENTID = l.STUDENTID
)
and l.LOCID = 3
Also, always use modern explicit join syntax instead of comma based join syntax.

Example table student and table payments:
id_student name id id_student datepayment
1 Lisa 1 1 2017-01-01
2 2 1 2017-02-03
3 Asher 3 2 2017-03-05
4 Lee 4 1 2017-03-03
SELECT a.name, a.datepayment
FROM
(SELECT s.name, p.datepayment
FROM
students s
LEFT OUTER JOIN payment p ON s.id_student = p.id_student) AS a
WHERE datepayment IS NULL;
Result:
name datepayment
Asher NULL
Lee NULL

Related

how to choose value in 1 column that must have 2 values in another - sql?

table:
id lesson
11 11 A
8 11 B
4 11 A
4 11 A
2 11 A
6 11 A
5 11 A
13 11 A
11 11 B
the id 11 has both taught in classroom 11A, 11B. How to select the ids that have both values 11a,11b?
I tried this with no luck:
select id from table where lesson in '11A' and lesson in '11B'
because it gives empty table, because it can't be both 11a and b at the same time.
If it's exectly two values you can make an inner join
select a.id
from myTable a
inner join myTable b
on a.id = b.id
and a.lesson = '11 A' and b.lesson = '11 B'
for obtain the id with both the lesson
if could try using a subquery for the involved id and the count if the id have more then a result
select id
FROM (
select id
from my_table
where lesson in ('11A', '11b')
) t
group by id
having count(*) = 2

Mysql join 3 tables query

I have 3 tables like following:
branch
id name
---------
1 abc
2 xyz
users
id branch_id name
-----------------
1 1 aa
2 1 bb
3 2 cc
4 1 dd
5 2 ee
sales
id user_id product price
1 1 xxxx 10
2 1 yyyy 20
3 2 zzzz 18
4 3 aaaa 12
5 2 bbbb 10
6 4 cccc 20
Now I want to get the total selling amount branch wise like:
branch_id total_price
---------------------
1 78
2 12
For that i write a sql query like:
SELECT SUM(s.price) , b.id
FROM sales s
JOIN branch b
GROUP BY id
HAVING s.user_id
IN (
SELECT id
FROM users
WHERE branch_id = b.id
)
But this does not provide the answer that I want. Please help me.
I think this should do the trick:
SELECT branch.id AS branch_id, SUM(s.price) AS total_price
FROM branch
JOIN users ON branch.id = users.branch_id
JOIN sales ON users.id = sales.user_id
GROUP BY branch.id;
Also you could use INNER JOIN instead of JOIN(Both are doing the same thing). With INNER JOIN it is possibly easier to read, especially your query contains other types of JOIN's like LEFT JOIN or RIGHT JOIN
Hope that helps!
You could use something like this:
SELECT u.branch_id, SUM(s.price) AS total_price
FROM sales AS s INNER JOIN users u ON s.user_id = user.id
GROUP BY u.branch_id
ORDER BY u.branch_id

How can I select classmates of a given student from a student-class association table?

If my table looks like the following, how can I select classmates of a given student?
student_class_assn
student_id class_id
1 1
2 1
3 1
4 2
5 2
6 3
For example, Student 1 has students 2 and 3 as classmates.
Please help me write a query that pivots on the known student_id and selects only the classmates (and not including the given student).
Here is an example using a sub-select. But can you help me write it with joins instead?
SET #KNOWN_STUDENT=1;
SELECT
student_id
FROM
student_class_assn
WHERE
class_id IN (
SELECT class_id FROM student_class_assn WHERE student_id = #KNOWN_STUDENT
)
AND student_id != #KNOWN_STUDENT;
Given my table above I expect the following results for each given student_id:
1 returns 2,3
2 returns 1,3
3 returns 1,2
4 returns 5
5 returns 4
6 returns NULL
all you need to do is just join the table and pass a conditional
SELECT t1.student_id
FROM student_class_assn t
JOIN student_class_assn t1
ON t1.class_id = t.student_id
AND t1.student_id <> 1
WHERE t.student_id = 1
FIDDLE
This will not show students with no classmates:
select s1.sid,group_concat(s2.sid order by s2.sid,',')
from
stud_class s1 inner join
stud_class s2 on s1.cid=s2.cid
where s1.sid <> s2.sid
group by s1.sid
order by 1

Update Duplicate column values based on Count in MySQl

I Have a Table like this
Employeeid Name CompanyID
1 Achal 1
2 Anil 1
3 Anil 1
4 Sachi 2
5 Anil 2
6 Sachi 1
7 Sachi 2
I want to update the names of the employee if multiple employees are there in a same company
My resultant table should be like this
Employeeid Name CompanyID
1 Achal 1
2 Anil(1) 1
3 Anil(2) 1
4 Sachi(1) 2
5 Anil 2
6 Sachi 1
7 Sachi(2) 2
My query is something like this
Update tblemplayee emp
join
(
select sname,count(*)
from tblemployee
group by sname,companyid
) innertable
on innertable.employeeid=emp.employeeid
set sname = concat(sname,'(', ,')') .
How can i change my query to get the result.
If you need to execute your query only once, you could use this query:
UPDATE
employees INNER JOIN (
SELECT e1.Employeeid, COUNT(e2.Employeeid) n
FROM
employees e1 INNER JOIN employees e2
ON e1.Name=e2.Name
AND e1.CompanyID=e2.CompanyID
AND e1.Employeeid>=e2.Employeeid
INNER JOIN (SELECT Name, CompanyID
FROM employees
GROUP BY Name, CompanyID
HAVING COUNT(*)>1) dup
ON e1.Name=dup.Name AND e1.CompanyID=dup.CompanyID
GROUP BY
e1.Employeeid, e1.Name) counts
ON employees.Employeeid = counts.Employeeid
SET
Name = CONCAT(Name, '(', counts.n, ')');
Please see fiddle here.

mySQL - GROUP BY but get the most recent row

I've got a budget table:
user_id product_id budget created
-----------------------------------------------------------------
1 1 300 2011-12-01
2 1 400 2011-12-01
1 1 500 2011-12-03
2 2 400 2011-12-04
I've also got a manager_user table, joining a manager with the user
user_id manager_id product_id
------------------------------------
1 5 1
1 9 2
2 5 1
2 5 2
3 5 1
What I'd like to do is grab each of the user that's assigned to Manager #5, and also get their 'budgets'... but only the most recent one.
Right now my statement looks like this:
SELECT * FROM manager_user mu
LEFT JOIN budget b
ON b.user_id = mu.user_id AND b.product_id = mu.product_id
WHERE mu.manager_id = 5
GROUP BY mu.user_id, mu.product_id
ORDER BY b.created DESC;
The problem is it doesn't pull the most recent budget. Any suggestions? Thanks!
To accomplish your task you can do as follows:
select b1.user_id,
b1.budget
from budget b1 inner join (
select b.user_id,
b.product_id,
max(created) lastdate
from budget b
group by b.user_id, b.product_id ) q
on b1.user_id=q.user_id and
b1.product_id=q.product_id and
b1.created=q.lastdate
where b1.user_id in
(select user_id from manager_user where manager_id = 5);
I'm assuming here that your (user_id, product_id, created) combination is unique.
For what it's worth, here's the code that returned what I was looking for:
SELECT DISTINCT(b1.id),mu.user_id,mu.product_id,b1.budget,b1.created
FROM budget b1
INNER JOIN (
SELECT b.user_id, b.product_id, MAX(created) lastdate
FROM budget b
GROUP BY b.user_id, b.product_id) q
ON b1.user_id=q.user_id AND
b1.product_id=q.product_id AND
b1.created=q.lastdate
RIGHT JOIN manager_user mu
ON mu.user_id = b1.user_id AND
mu.product_id = b1.product_id
WHERE mu.manager_id = 5;
Thanks for the help Andrea!