MySQL JOIN by SELECT earliest DATETIME - mysql

This query groups tickets by who they are assigned to and works out the average rounded number of days the ticket has taken to be closed.
SELECT a.id as theuser, round(avg(DATEDIFF( ta.dateClosed, t.dateAded ) * 1.0), 2) as avg
FROM tickets t join
mdl_user a
on find_in_set(a.id, t.assignedto) > 0
GROUP BY a.id ORDER BY avg ASC
I would now like to JOIN the ticketanswer table to find out the average time for first response.
The ticket could have multiple answers so i just want to get the first one.
Therefore I have tried to change the query to include this with no avail. Could anyone shed a light as to what im doing wrong?
SELECT a.id as theuser, round(avg(DATEDIFF( ta.dateAded , t.dateAded ) * 1.0), 2) as avg
FROM tickets t join
mdl_user a
on find_in_set(a.id, t.assignedto) > 0
INNER JOIN (SELECT MIN(ta.dateAded) as started FROM ticketanswer GROUP BY ta.ticketId) ta ON t.id = ta.ticketId
GROUP BY a.id ORDER BY avg ASC

Made some slight modifications to your query.
SELECT a.id as theuser, round(avg(DATEDIFF( ta.dateAded , t.dateAded ) * 1.0), 2) as avg
FROM tickets t join
mdl_user a
on find_in_set(a.id, t.assignedto) > 0
INNER JOIN (SELECT ticketid, MIN(dateAded) as started FROM ticketanswer GROUP BY ticketId) ta ON t.id = ta.ticketId
GROUP BY a.id ORDER BY avg ASC

Related

I need to get specific ids from db if these are in current and last quarter using SQL

[DB Table]
SELECT b.first_name, b.last_name, a.pod_name, a.category, c.user_id,
SUM(IF(QUARTER(CURDATE())-1 OR (QUARTER(CURDATE())-2) AND a.user_id, 1, 0)) AS flag FROM kudos a
INNER JOIN users b ON a.user_id = b.id INNER JOIN users_groups c ON a.user_id = c.user_id
INNER JOIN groups d ON c.group_id = d.id WHERE a.group_name = 'G2' AND d.id IN (7,8,9,11,12,13,14,15,16,17,21,22,23,24,25,26,27,28)
AND QUARTER(CURDATE())-1 = a.quarter ORDER BY a.final_score+0 DESC
I need to get the user_ids of those users which are both in quarter 1 and 2 from table.
Tried above query but failed to get expected results.
Can someone please guide me on this?
if you only need user_id then you can do this :
select user_id
from tablename
where quarter in (1,2)
group by user_id
having count(distinct quarter) = 2
another way is to use window function, assuming you have one user id in each quarter:
select * from (
select * , count(*) over (partition by user_id) cn
from tablename
where quarter in (1,2)
) t where cn = 2

Mysql Query to get latest record while using multiple joins, group by and sum()

SELECT Task_Entry_Icode, Task_Master_Icode, Work_Progress,SUM(A.Logged_Hours) as logged,B.*
FROM task_entry A INNER JOIN task_master B on A.Task_Master_Icode=B.Task_Icode
WHERE Task_Entry_Icode IN (
SELECT MAX(Task_Entry_Icode)
FROM task_entry
GROUP BY Task_Master_Icode
);
SELECT *
FROM task_master A INNER JOIN task_entry B ON A.Task_Icode=B.Task_Master_Icode
WHERE Created_On IN (
SELECT MAX(Created_On)
FROM task_entry
GROUP BY Task_Master_Icode
) AND A.Task_Created_By='7';
this works for me but if i use sum() it returns only one record
SELECT
B.Task_Entry_Icode,
B.Task_Master_Icode,
(SELECT Work_Progress FROM task_entry WHERE Task_Master_Icode=B.Task_Master_Icode ORDER BY B.Created_On DESC LIMIT 1 OFFSET 0),
SUM(B.Logged_Hours)
FROM
task_master A INNER JOIN task_entry B ON A.Task_Icode=B.Task_Master_Icode
GROUP BY
B.task_master_icode;

Inner join or other equal solution

I have good working sql query but I need to select also atribute from table advert. I tried with inner join but it wasn't successful. So this query is ok but I need to select one atribute from table advert.
SELECT D.* FROM details
WHERE (D.name LIKE ?) AND (D.id_advert IN(
SELECT A.id
FROM advert A
WHERE A.status=1 and duration >= CURDATE()
ORDER BY duration DESC ))
You can change the in (subquery ) in a proper inner join and the is simple use the columns form table A
SELECT D.* , A.*
FROM details
INNER JOIN advert A ON D.id_advert = A.id
AND A.status=1
AND duration >= CURDATE()
WHERE D.name LIKE ?
SELECT *
FROM details D
INNER JOIN advert A ON D.id_advert = A.id
INNER JOIN place P ON A.id_place = P.id
WHERE (D.NAME LIKE ?)
AND ( D.id_advert IN (
SELECT A.id
FROM advert A
WHERE A.STATUS = 1 AND duration >= CURDATE()
ORDER BY duration DESC
)
)
Here "?" is for search key. This query work perfect.

MySQL: where count is higher than average

I want to select posts from users who have specific followers which is higher than the overall average (compared to other users)
The problem is when I use AVG() it limits the number of posts/users coming through, yet I can't use GROUP BY j.id as it will break the average count and WHERE j2.fCount >= j2.oAvg stops working properly
Here's my code
SELECT * FROM (
SELECT j.*, ROUND(AVG(j.fCount)) as oAvg
FROM (
SELECT p.id , COUNT(fCount.id) as fCount
FROM `post` p
LEFT JOIN `table` table ON ...
LEFT JOIN `user` user ON ....
LEFT JOIN `follow` fCount ON fCount.user_id=user.id AND fCount.follow_id=table.ids
WHERE p.user_id=fCount.user_id
group by p.id
) j
---- > `GROUP BY j.id` - BREAKS THE AVERAGE BELOW
) j2
WHERE j2.fCount >= j2.oAvg
Thank you :)
because you're trying to compare to average, you might have to do your inner query twice like this.
SELECT *,
(SELECT AVG(fCount) as average FROM
(SELECT COUNT(fCount.id) as fCount
FROM post p
LEFT JOIN follow fCount ON fCount.user_id = p.user_id
GROUP BY p.id
)j1
)as average
FROM
(SELECT p2.id, COUNT(fCount2.id) as fCount
FROM post p2
LEFT JOIN follow fCount2 ON fCount2.user_id = p2.user_id
GROUP BY p2.id
)j2
HAVING fCount >= average
sqlfiddle
just replace inner queries of j1 and j2 with your j
if you just want to run inner query once you can use user-defined variables to total up your count divide it by count to calculate your own average like this
SELECT id,fCount,#sum/#count as average
FROM
(SELECT id,
fCount,
#sum := #sum + fCount as total,
#count := #count + 1 as posts
FROM
(SELECT p.id,COUNT(fCount.id) as fCount
FROM post p
LEFT JOIN follow fCount ON fCount.user_id = p.user_id
GROUP BY p.id
)j,
(SELECT #sum:=0.0,#count:=0.0)initialize
)T
HAVING fCount >= average
sqlfiddle

Sub Query counting character strings in MySQL

LEFT JOIN
(
SELECT user_id, review, COUNT(user_id) totalCount
FROM reviews
GROUP BY user_id
) b ON b.user_id= b.user_id
I am trying to fit WHERE LENGTH(review) > 100 in this somewhere but every I put it, it gives me problems.
The sub-query above counts all total reviews by user_id. I simply want to add one more qualification. Only count reviews greater than 100 length.
On a side note, I've seen the function CHAR_LENGTH -- not sure if that i what I need either.
EDIT:
Here is complete query working perfectly as expected for my needs:
static public $top_users = "
SELECT u.username, u.score,
(COALESCE(a.totalCount, 0) * 4) +
(COALESCE(b.totalCount, 0) * 5) +
(COALESCE(c.totalCount, 0) * 1) +
(COALESCE(d.totalCount, 0) * 2) +
(COALESCE(u.friend_points, 0)) AS totalScore
FROM users u
LEFT JOIN
(
SELECT user_id, COUNT(user_id) totalCount
FROM items
GROUP BY user_id
) a ON a.user_id= u.user_id
LEFT JOIN
(
SELECT user_id, COUNT(user_id) totalCount
FROM reviews
GROUP BY user_id
) b ON b.user_id= u.user_id
LEFT JOIN
(
SELECT user_id, COUNT(user_id) totalCount
FROM ratings
GROUP BY user_id
) c ON c.user_id = u.user_id
LEFT JOIN
(
SELECT user_id, COUNT(user_id) totalCount
FROM comments
GROUP BY user_id
) d ON d.user_id = u.user_id
ORDER BY totalScore DESC LIMIT 25;";
LENGTH() returns the length of the string measured in bytes. You probably want CHAR_LENGTH() as it will give you the actual characters.
SELECT user_id, review, COUNT(user_id) totalCount
FROM reviews
WHERE CHAR_LENGTH(review) > 100
GROUP BY user_id, review
You're also not using GROUP BY correctly.
See the documentation
The query that you want is:
LEFT JOIN
(
SELECT user_id, COUNT(user_id) totalCount,
sum(case when length(review) > 100 then 1 else 0 end
) as NumLongReviews
FROM reviews
GROUP BY user_id
) b ON b.user_id= b.user_id
This counts both the reviews and the "long" reviews. That count is done using a case statement nested in a sum() function.