Need to solve a MYSQL select query - mysql

SELECT
points.location_id,
route_locations.route_id
FROM
points
LEFT JOIN route_locations ON route_locations.location_id = points.location_id
WHERE
points.id = 199 OR points.id = 205
after this query I am getting this result..
route_id location_id
12 69
12 75
14 75
now I need the common value for location_id 69 and location_id 75.. ( here route_id 12)
How can I get that by Query..

You can try below query -
SELECT
route_locations.route_id
FROM points
JOIN route_locations ON route_locations.location_id = points.location_id
WHERE
points.id in (199,205)
group by route_locations.route_id
having count(points.location_id)=2

Related

get unique records from mysql

Please check this query. Actually, I want to fetch only two records, not 4 records. I should get last record per from_member_id and to_member_id. Currently, I get two records for it. Please let me know what I am doing wrong in the query
Query:
SELECT DISTINCT from_member_id, to_member_id
FROM `single_chat`
where from_member_id = 175 or to_member_id = 175
group by from_member_id, to_member_id
Desired output
175 176
175 177
You can try the below - DEMO
SELECT distinct
t2.from_member_id,t2.to_member_id
FROM single_chat t1
JOIN single_chat t2 on t1.from_member_id=t2.to_member_id
and t1.to_member_id < t2.to_member_id
where t1.from_member_id = 175 or t1.to_member_id = 175
OUTPUT:
f_id t_id
175 176
175 177

Select corresponding value from second table (Mysql)

Struggling with some sql, would appreciate some guidance.
Have two tables logs and sense
logs –
assetid ts nodeid status
1 2017-10-26 14:00:10 73 240
2 2017-10-26 14:00:06 21 160
3 2017-10-26 14:00:04 18 230
4 2017-10-26 14:00:02 19 400
5 2017-10-26 14:00:00 21 190
1 2017-10-26 13:20:08 18 20
2 2017-10-26 13:06:10 20 160
3 2017-10-26 13:03:04 17 230
sense –
status value
20 5
160 37
190 39
230 56
240 58
400 90
Trying to find the correct syntax to only show the latest record (in datetime) of each assetid and then show the corresponding value from the sense table (based on the matching status in both tables) to produce –
assetid ts nodeid status value
1 2017-10-26 14:00:10 73 240 58
2 2017-10-26 14:00:06 21 160 37
3 2017-10-26 14:00:04 18 230 56
4 2017-10-26 14:00:02 19 400 90
5 2017-10-26 14:00:00 21 190 39
Have tried –
Select assetid, ts, nodeid, status, value
From
logs
Join sense X on X.status = logs.status
Group by assetid
Order by ts DESC
But this only outputs 1 row (instead of 5)
assetid ts nodeid status value
1 2017-10-26 14:00:10 73 240 58
Removing
Join sense X on X.status = logs.status
of course outputs all records but that is not required.
Thoughts appreciated.
Regards
Active
Actually your query is returning 5 rows, 1 for each id. But it won't return rows with latest ts for each id. You can verify this by clicking on the link for demo. You can compare results of both queries.
To achieve this task,following query will help you:
Select l.assetid, l.ts, logs.nodeid, X.status, X.value
From
logs
inner Join sense X on X.status = logs.status
inner join (select assetid, max(ts) as ts from logs group by assetid) l
on l.assetid = logs.assetid and logs.ts = l.ts
Group by l.assetid
Order by l.ts DESC;
Click here for Demo
EDIT:
If dataype of ts is string then replace max(ts) in above query with:
max(str_to_date(ts,'%d%m%y'))
Feel free to ask any doubts.
Hope it helps!
Try this
Select a1.assetid, MAX(a1.ts), a1.nodeid, a1.status, X.value
From
logs a1
inner join sense X on X.status = a1.status
Group by assetid, a1.nodeid, a1.status, X.value
Order by ts DESC
Use GROUP BY to find minimum for each assetid and then JOIN with the logs and sense
Select *
FROM logs l
JOIN sense s ON s.status = l.status
JOIN
(
Select assetid, max(ts) maxts
From logs
Group by assetid
) t ON t.assetid = l.assetid and l.ts = t.maxts
demo
On MY SQL 8.0.2
WITH CTE as
(
Select A.assetid, A.ts, A.nodeid, A.status, B.value, row_number() over(PARTITION BY A.assetid ORDER BY A.ts DESC) AS rn
from logs as A
inner join sense B ON A.status=B.status
)
SELECT *
FROM CTE
WHERE rn='1';

select unique row as per latest created_at time

this is my query:
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC
what I am getting:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
50 pinal to prem 2016-02-19 12:20:00 73
50 prem to premal-joshi 2016-02-19 11:40:52 78
18 prem to mukund 2016-02-19 11:21:52 77
18 pinal to mukund 2016-02-18 11:37:00 76
9 mukund rate to mitesh 2016-02-15 22:34:14 51
9 Not a bad. 2016-02-10 00:16:31 45
9 sda 2016-02-08 01:36:33 39
what I want:
rat_id rating_comment created_at id
18 superb developer 2016-02-19 18:26:54 82
9 james to manoj-joshi 2016-02-19 16:42:17 84
50 james to prem 2016-02-19 13:05:30 83
Try This
SELECT rat_id,rating_comment, MAX(created_at) AS created, id FROM (
SELECT br.employee_id AS rat_id,
br.rating_comment,
br.created_at,
br.id
FROM employee_followers
LEFT JOIN employee_ratings AS br ON employee_followers. employee_id = br.employee_id
WHERE employee_followers.employee_id IN
(SELECT `employee_id`
FROM employee_followers
WHERE user_id =32)
GROUP BY br.id
ORDER BY created_at DESC) AS temp GROUP BY temp.rat_id
It seems that you want only the latest record per employee_id. You can use a derived table to get the maximum date, then join again to get all fields from employee_ratings table for this date:
SELECT er.employee_id AS rat_id,
er.rating_comment,
er.created_at,
er.id
FROM employee_followers AS ef
LEFT JOIN (
SELECT employee_id, MAX(created_at) AS max_date
FROM employee_ratings
GROUP BY employee_id
) AS emp_max ON ef.employee_id = emp_max.employee_id
LEFT JOIN employee_ratings AS er
ON emp_max.employee_id = er.employee_id AND
emp_max.max_date = er.max_date
WHERE user_id = 32
ORDER BY created_at DESC
I have also removed GROUP BY br.id that seems to be redundant in the context of the query. Also IN operator can be replaced by user_id = 32 since you are selecting from the same table.

How to group by rows with most recent order?

Updated:
Here is the demo and current result based on M Khalid Junaid's answer. The query still doesn't output my expected result.
I have a very simple table and here is the values.
id animal_id latitude longitude created_at
--------------------------------------------------------------------------
119 75 1.356203 103.828140 2014-04-30 15:00:04
118 75 1.296613 103.857079 2014-04-30 14:58:58
117 75 1.296613 103.857079 2014-04-30 14:58:20
116 75 1.296613 103.857079 2014-04-30 14:53:17
Here is my query and I want to GROUP if latitude, longitude and user_id is same.
select p.id,p.animal_id,p.name,p.latitude,p.longitude,p.created_at from Photo p
where 5 >= (select count(*)
from Photo p2
where p2.animal_id = p.animal_id and
p2.id <= p.id
)
AND DATE(p.created_at) > DATE_SUB(NOW(),INTERVAL 13 DAY)
AND ( p.latitude BETWEEN 0.908862 AND 1.717581 ) AND ( p.longitude BETWEEN 103.584595 AND 104.098206 )
GROUP BY p.latitude,p.longitude,p.animal_id
ORDER BY p.created_at DESC;
Current result id = 116
id animal_id latitude longitude created_at
--------------------------------------------------------------------------
119 75 1.356203 103.828140 2014-04-30 15:00:04
116 75 1.296613 103.857079 2014-04-30 14:53:17
Expected result id = 118
I want to get most recent result when I group latitude,longitude,uer_id
id animal_id latitude longitude created_at
--------------------------------------------------------------------------
119 75 1.356203 103.828140 2014-04-30 15:00:04
118 75 1.296613 103.857079 2014-04-30 14:58:58
I've tried several ways but couldn't get the desired result.
Use a self join,results from group by are indeterminate and can't guarantee you the latest row for the group
select p.id,p.animal_id,
p.latitude,p.longitude,p.created_at
from Photo p
JOIN (SELECT MAX(id) id,latitude,longitude,animal_id
FROM Photo
GROUP BY latitude,longitude,animal_id
) p1 ON(p.id = p1.id)
where 5 >= (select count(*)
from Photo p2
where p2.animal_id = p.animal_id and
p2.id <= p.id)
AND DATE(p.created_at) > DATE_SUB(NOW(),INTERVAL 13 DAY)
AND ( p.latitude BETWEEN 0.908862 AND 1.717581 )
AND ( p.longitude BETWEEN 103.584595 AND 104.098206 )
GROUP BY p.latitude,p.longitude,p.animal_id
ORDER BY p.created_at DESC;
Demo
Finally I've managed to find my own answer. Thanks everyone for sharing your time.
SELECT p.id,p.animal_id,p.latitude,p.longitude,p.created_at
-- This will make sure that `GROUP BY` will pickup most recent result
FROM (SELECT id,animal_id,latitude,longitude,created_at from Photo ORDER BY id DESC) p
-- Pick 5 rows for each animal_id. Meaning, there can be multiple photo of animal but MAX is 5.
WHERE 5 >= (select count(*)
from (SELECT * from Photo p4 GROUP BY latitude,longitude,animal_id) p2
where p2.animal_id = p.animal_id and
p2.id >= p.id
)
-- We want Photos uploaded 5 days ago
AND DATE(p.created_at) > DATE_SUB(NOW(),INTERVAL 15 DAY)
-- Plus, only photos within given Map Bound
AND ( p.latitude BETWEEN 0.908862 AND 1.717581 ) AND ( p.longitude BETWEEN 103.584595 AND 104.098206 )
-- This will help to remove duplicate images in same location of same animal. We will see only most recent photo in each exact lat,lng location
GROUP BY p.latitude,p.longitude,p.animal_id
ORDER BY id DESC;
It's may be tricky solution. You can concatenate latitude,longitude,animal_id in the group statement like this :
group by concat(latitude, longitude, animal_id)

MySQL calculate difference in count column between two queries

I have two different queries. One for "plus" and one for "minus". I want to find the difference in the count value for each player.
I tried union all and got some very weird numbers.
Here are the results of each query which I ned to find the difference of:
fk_plus_player1_id cnt
90 71
65 68
79 66
45 59
64 57
27 56
55 56
93 55
37 55
40 44
1 36
84 33
20 31
24 28
8 23
fk_minus_player1_id cnt
93 44
64 42
79 40
37 35
90 33
20 31
84 31
27 30
65 30
40 26
1 26
24 25
45 25
55 22
8 10
How would I accomplish this? Thanks in advance for your help. I am a noob...
UGH...Trying to do the join method. Having issues, getting no results, just 4 empty columns. This is what I am trying
SELECT
*
FROM
(
SELECT
statement for plus results here
) AS tp
JOIN (
SELECT
statement for minus results here
) AS tm ON tp.fk_plus_player1_id = tm.fk_minus_player1_id
GROUP BY
fk_plus_player1_id
suggestions??
You have two tables.
You want for each player, the difference of the counts.
So :
SELECT t1.fk_minus_player1_id AS player, ABS(t1.cnt - t2.cnt) AS difference
FROM table1 t1, table2 t2
WHERE t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id;
Maybe this is what you're looking for ?
WITH query1 AS
(SELECT t1.fk_minus_player1_id AS player, (t1.cnt - IFNULL(t2.cnt,0)) AS difference
FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id),
query2 AS (SELECT t2.fk_plus_player1_id AS player, (IFNULL(t1.cnt,0) - t2.cnt) AS difference
FROM table2 t2 LEFT OUTER JOIN table1 t1 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t2.fk_plus_player1_id)
(SELECT player, difference
FROM query1)
UNION
(SELECT player, difference
FROM query2 WHERE player NOT IN (SELECT player FROM query1))
You run the risk that the same players are not in both lists. The solution is union all with group by:
select player1id, sum(pluscnt) as pluscnt, sum(minuscnt) as minuscnt,
(sum(pluscnt) - sum(minuscnt)) as diff
from ((select player1id, cnt as pluscnt, 0 as minuscnt
from plustable
) union all
(select player1id, 0, cnt
from minustable
)
) t
group by player1id;