mysql query taking long time to respond - mysql

SELECT t.id
, t.department
, t.owner
, t.client
, u.username as owner_name
, c.name as catagery
, d.dept_name as deptname
, t.periority
, t.status
, t.estimate
, cl.takeaway_name
from tbl_task t
JOIN tbl_user u
ON u.id = t.owner
JOIN tbl_task_catagery c
ON c.id = t.catagery
JOIN tbl_department d
ON d.id = t.department
JOIN tbl_clients cl
ON cl.id = t.client
and t.status = 0
and (t.id in (select task_id
from tbl_task_note tn
where tn.user_id = '69'
and tn.id in (select max(id)
from tbl_task_note tt
where tt.task_id = tn.task_id
)
)
)
order by t.id
Note : The above query is used for check users hold tasks. tbl_task_note table is used for check task notes for separate users task.

With this query you will get the task that have the last task_note registered, including the user, departament, client, and some other.
If it is what you need you can just do this.
select
t.id,
t.department,
t.owner,
t.client,
u.username as owner_name,
c.name as catagery,
d.dept_name as ptname,
t.periority,
t.status,
t.estimate,
cl.takeaway_name
from tbl_task t
INNER JOIN tbl_user u ON u.id=t.owner
INNER JOIN tbl_task_catagery c ON c.id=t.catagery
INNER JOIN tbl_department d ON d.id=t.department
INNER JOIN tbl_clients cl ON cl.id=t.client and t.status=0
INNER JOIN (select * from tbl_task_note where id =
(select max(id) from tbl_task_note)
)tb on tb.task_id = t.id
order by t.id
That way you can improve your query.
You shoud also ensure that your keys compared are foreign keys to get faster consults.

Related

How to select data from mutiple tables in SQL instead of SELECT statements?

I have used SELECT statements to select data from multiple tables but it takes long time to execute this query.
select t.id,
t.department,
t.owner,
t.client,
(select username from tbl_user u where u.id = t.owner) as owner_name,
(select name from tbl_task_catagery c where c.id = t.catagery) as catagery,
(select dept_name from tbl_department d where d.id = t.department) as deptname,
(select name from tbl_task_catagery c where c.id = t.subcatagery) as subcatagery,
t.periority,
t.status,
t.estimate,
c.takeaway_name
from tbl_task t,
tbl_clients c
where c.id = t.client
and t.status = 0
and (t.id in (select task_id
from tbl_task_note tn
where tn.user_id = '130'
and tn.id in (select max(id)
from tbl_task_note tt
where tt.task_id = tn.task_id)))
order by t.id
How to do it in an easier way?
You may over-simplify your query to:
select t.id,
t.department,
t.owner,
t.client,
(select username from tbl_user u where u.id = t.owner) as owner_name,
(select name from tbl_task_catagery c where c.id = t.catagery) as catagery,
(select dept_name from tbl_department d where d.id = t.department) as deptname,
(select name from tbl_task_catagery c where c.id = t.subcatagery) as subcatagery,
t.periority,
t.status,
t.estimate,
c.takeaway_name
from tbl_task t
join tbl_clients c on c.id = t.client
where t.status = 0
and exists (select 1
from tbl_task_note tn
where tn.user_id = '130'
and t.id = tn.task_id
order by id desc
limit 1)
Then, you can have indices on tbl_task(status, client) and tbl_clients(id). Presumably, tbl_clients(id) is the primary key so already have an index over it.

Get Value from INNER JOIN 3 table with LASTEST RECORD from each table

I get problem to get value from some of tables. You can see picture below, I wanna get row what I block with red color.
I try with code below
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN job_experience AS ex
ON p.email = (SELECT ex.email
FROM job_experience
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_education AS e
ON p.email = (SELECT e.email
FROM job_education
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_applying AS j
ON p.email = (SELECT j.email
FROM job_applying
ORDER BY ex.id DESC
LIMIT 1)
You need correlated sub-queries.
Find the latest id for each email in all the three tables
SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id)
FROM job_experience b
WHERE a.email = b.email)
The above query will find the latest id for each email in job_experience table. Do the same for other two tables as well, then join the result with job_jobseeker table to get the result.
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN (SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id) FROM job_experience b
WHERE a.email = b.email)) AS ex
ON p.email = ex.email
INNER JOIN (SELECT email, //Just called column without initialize
degree,
majority
FROM job_education a
WHERE a.id = (SELECT Max(b.id) FROM job_education b
WHERE a.email = b.email)) AS e
ON p.email = e.email
INNER JOIN (SELECT email, //Just called column without initialize
division
FROM job_applying a
WHERE a.id = (SELECT Max(b.id) FROM job_applying b
WHERE a.email = b.email)) AS j
ON p.email = j.email

sql select distinc where max date

I have 3 tables "maintenances", "cars", "users" . I want to select all data from table maintenance with a distinct car_id and the last record for each distinct (based on max maintenance_date)
SELECT
m. * , u.username, c.Model, c.Make, c.License, c.Milage, COUNT( m.process_id ) AS count_nr
FROM
maintenances AS m
LEFT JOIN users AS u ON u.id = m.user_id
LEFT JOIN cars AS c ON c.id = m.car_id
WHERE
maintenance_date = (SELECT MAX(maintenance_date) FROM maintenances WHERE car_id = m.car_id)
The problem is that this query returns only one record which has the max date from all records. I want all records (distinct car_id and from records with the same car_id to display only values for max(maintenance_date))
This is your query:
SELECT m. * , u.username, c.Model, c.Make, c.License, c.Milage, COUNT( m.process_id ) AS count_nr
----------------------------------------------------------------^
FROM maintenances AS m LEFT JOIN
users AS u
ON u.id = m.user_id LEFT JOIN
cars AS c
ON c.id = m.car_id
WHERE maintenance_date = (SELECT MAX(maintenance_date) FROM maintenances WHERE car_id = m.car_id);
It is an aggregation query. Without a group by, only one row is returned (all the rows are in one group). So, add the group by:
SELECT m. * , u.username, c.Model, c.Make, c.License, c.Milage, COUNT( m.process_id ) AS count_nr
FROM maintenances AS m LEFT JOIN
users AS u
ON u.id = m.user_id LEFT JOIN
cars AS c
ON c.id = m.car_id
WHERE maintenance_date = (SELECT MAX(m2.maintenance_date) FROM maintenances m2 WHERE m2.car_id = m.car_id);
GROUP BY c.id
I also fixed the correlation statement, to be clear that it is correlated to the outer query.
add GROUP BY u.username .
WHERE
maintenance_date = (SELECT MAX(maintenance_date) FROM maintenances WHERE car_id = m.car_id)
GROUP BY u.username

Getting 2 same fields in the same time

I've 3 tables below. (sample)(mySql script)
customer
cust_id
cust_name
user_id
user_id_2
user
user_id
em_id
employee
em_id
em_name
How can I call the em_name field for user_id, and em_name field for user_id_2 by crossing user table in the same time with join??
Try this
SELECT q1.* ,
q2.em_name AS 'em_name_2'
FROM (SELECT c.cust_id ,
c.cust_name ,
c.user_id ,
c.user_id_2 ,
e.em_name
FROM dbo.customer AS c
INNER JOIN dbo.[user] AS u ON c.user_id = u.user_id
INNER JOIN dbo.employee AS e ON u.em_id = e.em_id
) q1
CROSS JOIN
( SELECT e.em_id ,
e.em_name
FROM dbo.customer AS c
INNER JOIN dbo.[user] AS u ON c.user_id_2 = u.user_id
INNER JOIN dbo.employee AS e ON u.em_id = e.em_id
) q2

Gathering multiple fields

$q = "SELECT s.id, s.title, s.description,
(SELECT COUNT(*) FROM ".FORUM_THREADS." t WHERE t.cat_id = s.id) AS topics,
(SELECT COUNT(*) FROM ".FORUM_REPLIES." r INNER JOIN ".FORUM_THREADS." t ON r.thread_id = t.id
WHERE t.cat_id = s.id) AS replies,
(SELECT r.date FROM ".FORUM_REPLIES." r INNER JOIN ".FORUM_THREADS." t ON r.thread_id = t.id
WHERE t.cat_id = s.id ORDER BY r.date DESC LIMIT 1) AS last_post
FROM ".FORUM_SUBCATEGORIES." s WHERE s.parent = '$catid' AND s.status = '0' ORDER BY s.id";
I am attempting to select more than one field on the following part of the query
(SELECT r.date FROM ".FORUM_REPLIES." r INNER JOIN ".FORUM_THREADS." t ON r.thread_id = t.id
INNER JOIN ".TBL_USERS." u ON u.id = r.author WHERE t.cat_id = s.id ORDER BY r.date DESC LIMIT 1) AS last_post
Along with r.date, I want to select u.username and r.author.
How can I go about doing this?
Thanks!
Just add them to the SELECT:
(SELECT r.date, r.author, u.username FROM ".FORUM_REPLIES." r INNER JOIN ".FORUM_THREADS." t ON r.thread_id = t.id
INNER JOIN ".TBL_USERS." u ON u.id = r.author WHERE t.cat_id = s.id ORDER BY r.date DESC LIMIT 1) AS last_post
UPDATED after comment from OP:
You need to do 3 separate selects OR (depending on your data model) change the query so that the last_post query ends up after/in the FROM clause (there it can have as many columns as you want)...
Luke, you have a central select statement which uses nested select statements for getting the count. You can't depend on the nested select statements to count as the inner join, so you're going to have to add them to the central select statement instead.
In other words, join ".FORUM_REPLIES." and "u" (not sure what that's supposed to represent) with ".FORUM_SUBCATEGORIES.". I'd write the query for you, but I don't know how to link subcategories with replies and subcategories with u.