Need Mysql Query for Search Bus from stop and To Stop - php

I create Table for Buses and Route and Stop tables
Buses Table
id , bus_name
1 AAA
2 BBB
Stop Table
id, stop_name, latitude, longitude
1 XYZ 12.5555 77.222
2 SSS 13.5555 77.2888
3 EEE 88.444 77.222
4 C 34.8859309 -97.47070
5 JJJ 32.9902355 -97.99804
route Table
id, bus_id, stop_id, arrival_time, departure_time, START_END_STOP
1 1 1 0000 8.00AM START
2 1 2 8.10AM 8.10AM
3 1 3 8.15AM 8.16AM
4 1 4 8.20AM 8.20AM
5 1 5 8.25AM 0000 END
6 2 1 0000 8.10AM START
7 2 3 8.15AM 8.18AM
8 2 5 8.27AM 0000 END
Now I search from Stop XYZ to JJJ
I Want Result is
bus_name from_stop_name departure_time to_stop_name arrival_time Notes
AAA XYZ 8.00AM JJJ 8.25AM NIL
BBB XYZ 8.10AM JJJ 8.27AM NIL
Or I search Stop from XYZ to C
bus_name from_stop_name departure_time to_stop_name arrival_time Notes
AAA XYZ 8.00AM C 8.20AM NIL
BBB XYZ 8.10AM JJJ 8.27AM JJJ to C is 600 Mts
I Need Mysql Selecting Query , Please help Me.
thanks

I think that the query below will give you the desired results. It would be better to parameterize the inputs as to make the query more general.
select buses.bus_name, s1.stop_name as from_stop_name, t1.departure_time,
s2.stop_name as to_stop_name, t2.arrival_time
from buses
inner join table t1 on t1.bus_id = buses.id
inner join stop s1 on s1.id = t1.stop_id
inner join table t2 on t2.bud_id = buses.id
inner join stop s2 on s2.id = t2.stop_id
where buses.bus_name in ('AAA', 'BBB')
and s1.stop_name = 'XYZ'
and s2.stop_name = 'JJJ'

You can try below query. we need to write input param 'stop_name' at 4 places in query.
Table name are
buses, route and stops used in below query
select A.name, A.departure_time, A.from_stop_name, RO.arrival_time,
'JJJ' as to_stop_name from
(select bus_id, name, departure_time,
stop_name as from_stop_name from route R left join stops S on
R.stop_id = S.id left join buses B on bus_id = B.id where stop_id in
(select id from stops where stop_name in ('XYZ', 'JJJ')) group by
bus_id having count(distinct stop_id) = 2) A
left join
route RO on
A.bus_id = RO.bus_id and RO.stop_id in (SELECT id from stops where
stop_name = 'JJJ');

SELECT `B`.`bus_name`,
`from_stop`.`stop_name` AS `from_top_time`,
`Departure`.`departure_time`,
`to_stop`.`stop_name` AS `to_stop_name`,
`Arrival`.`arrival_time`
FROM `buses` `B`
JOIN `route` `Departure`
ON `Departure`.`bus_id` = `B`.`id`
JOIN `route` `Arrival`
ON `Arrival`.`bus_id` = `B`.`id`
JOIN `stop` `from_stop`
ON `Departure`.`stop_id` = `from_stop`.`id`
JOIN `stop` `to_stop`
ON `Arrival`.`stop_id` = `to_stop`.`id`
WHERE ( `from_stop`.`stop_name` = 'XYZ'
AND `to_stop`.`stop_name` = 'JJJ' )
OR ( `from_stop`.`stop_name` = 'XYZ'
AND `to_stop`.`stop_name` = 'C' )
GROUP BY `B`.`id`

Related

Count workers in business with branches

Select a group, where is one Main and for example 5 Branch. So, the total of places is 6. In each of those 6, search for 3 workers, who is working as job_types LIKE "%C%". If, in one of those 6 places, are 3workers with given parameter, query must get results of all those 6 places.
To clarify: 3 workers must be working in same main/branch.
Because project itself is very dificult, it would be better, to get results using RAW query:
business table
id | mainorbranch | name
--------------------------------------
1 Main Apple
2 Branch Apple London
3 Branch Apple Manchester
4 Main IBM
5 Branch IBM London
etc ...
Relationship
business_branches table
b_id | branch_id | id
--------------------------------------
1 1 1
2 2 1
3 3 1
4 4 4
5 5 4
// etc
people_details table
d_id | id | job_types
--------------------------------------
1 1 C
2 3 D
3 2 F
4 4 C
5 5 C
// etc
people_branches table
pb_id | branch_id | id
--------------------------------------
1 1 3
2 3 2
3 4 4
4 2 5
5 1 1
// etc
What i need to get:
Business id | Name | Postcode
-----------------------------------------
1 Apple postcode
2 Apple 232 postcode
3 Apple 323 postcode
// etc...
DB Structure for Helpers
http://sqlfiddle.com/#!9/206733
Simplified, minified SQL file with total of 110k+ rows
UPDATE
Answer by #KikiTheOne is kinda working, but it gets only half a results. Other half is missing.
as discussed in Chat. here is a solution:
if u Need Company Infos... get them # t1.XXXX like postcode.
i changed
"pb_id" "branch_id" "id"
"1" "1" "3"
"2" "3" "2"
"3" "1" "4"
"4" "1" "5"
"5" "1" "1"
so i get 3 People in 1 branch
SELECT
t1.id as "Business id",
t1.name as Name,
'postcode' as "Postcode"
FROM SO_business as t1 inner join
(
SELECT * FROM SO_busness_branches as t3
inner join
(
SELECT
t5.branch_id as inner_branch,
count(t5.branch_id) as workers_in,
max(t6.job_types) as job_types,
max(t7.id) as mainbranch
FROM
SO_people_branches as t5
inner join SO_people_details as t6
on t5.id = t6.id
inner join SO_busness_branches as t7
on t5.branch_id = t7.branch_id
WHERE
t6.job_types LIKE '%C%'
GROUP BY
t5.branch_id
) as t4
on t3.id = t4.inner_branch
WHERE t4.workers_in >= 3
) as t2
on t1.id = t2.branch_id
Explanation:
-.1 the Most inner SQL Counts ALL branches with workers ( number of workers init ) and Job_type = %c% and joines the MAIN id of the branch.
-.2 the second SQL gets that info and only selects all branches with workers >= 3
-.3 the outer SQL selects all inner INFOS and gives back ALL branches/main with the branchID-Main from the Inner SQL. AND connects them to the Business table so u can Display all Infos likepostcode from there
hope that this works as it's not as easy to interpret the relationships with the name of the columns in your question.
With this script you can add any group of main/branch to search into
SELECT b.id, b.name, 'postcode' as postcode
FROM business b
INNER JOIN business_branches bb ON (bb.branch_id = b.id)
WHERE bb.id IN (
SELECT bb1.id FROM people_details pd
INNER JOIN people_branches pb ON (pb.id = pd.id)
INNER JOIN business_branches bb1 ON (bb1.branch_id = pb.branch_id)
INNER JOIN business b1 ON (b1.id = bb1.branch_id)
WHERE
pd.job_types like '%C%' AND
bb1.id IN (1,4) -- You can add as many group of businesses (main/branch combinations) using the main branch key
GROUP BY pb.branch_id HAVING count(pb.branch_id) >= 3
)

how to select records based on recent date in mysql

I have 3 tables like below :
hr_emp_job_compensation:
id date fkEmp_id basic_wage part_hours part_amt
1 04-01-2016 1 4500 35 120
2 04-01-2016 3 3800 30 150
3 08-01-2016 3 3200 30 100
hr_emp_job_info:
id fkEmp_id
1 1
2 3
hr_emp_info:
id employee_id first_name
1 001 Ram
2 002 Lak
3 003 jai
4 004 shiva
I want to select records from table 1 , based on the column Date value is higher.
I Try the following query :
SELECT t1.fkEmp_id,max(t1.date),max(t1.id) as uid,t1.part_hours,t1.part_amt, t3.first_name, t3.employee_id
FROM `hr_emp_job_compensation` as t1
inner join `hr_emp_job_info` as t2 on t1.fkEmp_id = t2.fkEmp_id
left join `hr_emp_info` as t3 on t3.id = t1.fkEmp_id
group by t1.fkEmp_id
But the result is look like below :
fkEmp_id max(t1.date) uid part_hours part_amt first_name employee_id
1 2016-01-04 1 35 120 Ram 001
3 2016-01-08 3 30 150 Jai 003
Here the part_hours and part_amt columns are fetched from the id 2. How to change the query.
No need to add MAX() for the dateand id. You can handle the MAX(date) in the WHERE clause.
SELECT t1.fkEmp_id, t1.date as `date`, t1.id as uid,
t1.part_hours, t1.part_amt,
t3.first_name, t3.employee_id
FROM `hr_emp_job_compensation` as t1
INNER JOIN `hr_emp_job_info` as t2 on t2.fkEmp_id = t1.fkEmp_id
LEFT JOIN `hr_emp_info` as t3 on t3.id = t1.fkEmp_id
WHERE t1.`date`= ( SELECT MAX(`date`)
FROM `hr_emp_job_compensation`
WHERE fkEmp_id = t1.fkEmp_id);
Please find the Working Demo

Mysql select multiple count giving wrong values

I'm trying to find a patient's appointments and messages count. My table records are like below 3 table patient, appointments and messages
Patient table
pid fname lname
1 john sid
2 rother ford
3 megan rough
4 louis kane
appointments table
id pid appointment_date
1 1 2015-08-04
2 2 2015-08-05
3 1 2015-08-06
4 1 2015-08-07
5 3 2015-08-07
6 2 2015-08-08
7 4 2015-08-13
8 1 2015-08-12
Messages table
id pid description message_date
1 2 join 2015-08-04
2 2 update 2015-08-05
3 3 join 2015-08-05
4 4 update 2015-08-10
5 3 test 2015-08-07
So if write query to find counts i'm getting wrong values
SELECT pd.fname,pd.lname , pd.pid, COUNT( a.id ) AS app_cnt, COUNT( m.id ) AS mes_cnt
FROM patient pd
LEFT OUTER JOIN appointments a ON a.pid = pd.pid
LEFT OUTER JOIN messages m ON m.pid = pd.pid
GROUP BY pd.pid
ORDER BY pd.pid
fname lname pid app_cnt mes_cnt
john sid 1 4 0
rother ford 2 4 4
megan rough 3 2 2
louis kane 4 1 1
Here pid 1 have 4 appointments and 0 messages, pid 2 have 2 appointments and 2 messages but getting wrong values.
Can someone please help to resolve this issue. I'm not interested in writing sub queries for this.
Functionality looks simple but I'm really facing problem for writing query.
Anymore suggestions please.
After thoroughly analysing your problem and tables, It cannot be done directly using simple query as LEFT OUTER JOIN is returning some superfluous records, that's why to filter it, you will have to use temporary table and modify the query as:
Select temp.fname, temp.lname, temp.pid, a_count, count(m.pid) as m_count from
(SELECT fname,lname,pd.pid, count(a.pid) as a_count
FROM patients pd
LEFT OUTER JOIN appointments a ON a.pid = pd.pid group by pd.pid) temp
LEFT OUTER JOIN messages m ON m.pid = temp.pid
group by temp.pid
Explanation:
It will join patients and appointments table and group them by pid so that messages from message table do not repeat for each patients.pid.
The wrong result is as a result of left outer join as it is giving wrong results for this query
SELECT *
FROM patients pd
LEFT OUTER JOIN appointments a ON a.pid = pd.pid
LEFT OUTER JOIN messages m ON m.pid = pd.pid
Since we need to limit the results of first two joins, hence temporary table is necessary.

How To Use Max function with group by using MYSQL

I have those 3 tables
candidates
cdid cdname
1 Moussa
2 Moustafa
3 Haitham
positions
posid posname
1 pos1
2 pos2
3 pos3
joboffers
cdid posid salary
1 1 600
1 2 800
1 3 700
2 1 500
2 2 700
2 3 900
3 2 1000
3 3 500
I need to make a query that get the cdname with max salary for every position
the table should be like this
cdname posname salary
moussa pos1 600
haitham pos2 1000
moustafa pos3 900
I am using this query but it's not getting the correct cdid
$sql="select joboffers.cdid,joboffers.posid,Max(joboffers.salary),candidates.cdname
FROM joboffers,candidates
Where joboffers.cdid=candidates.cdid
Group by joboffers.posid";
Try this :)
SELECT sub.cdname, sub.posname, sub.salary
FROM (
SELECT * FROM joboffers jo
INNER JOIN positions ps USING (posid)
INNER JOIN candidates cd USING (cdid)
ORDER BY posid, salary DESC
) sub
GROUP BY sub.posid
I think you need to group by all non-aggregated columns, like this:
SELECT j.cdid, c.cdname, j.posid, MAX(j.salary)
FROM joboffers j
JOIN candidates c ON j.cdid = c.cdid
GROUP BY j.cdid, c.cdname, j.posid
SELECT c.cdname, p.posname, MAX(j.salary)
FROM joboffers j
INNER JOIN candidates c ON j.cdid = c.cdid
INNER JOIN positions p ON j.posid = p.posid
GROUP BY c.cdname, p.posname
enter code hereSELECT customerNumber, MAX(amount)
FROM payments
GROUP BY customerNumber
ORDER BY MAX(amount);

PHP MySQL Highscore table

Im joining 3 tables to present a table with users highest score
My tables
game_log:
---ID---user_ID---score---time---
| 1 52 567 10 |
| 2 53 641 13 |
| 3 52 465 8 |
| 4 53 451 14 |
---------------------------------
users:
---ID---name---countyid---
| 52 Dave 1 |
| 53 John 2 |
------------------------
county:
---countyid---countyname---
| 1 Orange wichit |
| 2 Orange clemts |
--------------------------
SQL:
SELECT * FROM game_log
INNER JOIN users ON game_log.user_ID=users.ID
INNER JOIN county ON users.countyid=county.countyid
ORDER BY game_log.score DESC , game_log.time LIMIT 20";
Above code gives me this result:
Rank---Name--------County------Score---Time
1 John Orange clemts 641 13
2 Dave Orange wichit 567 10
3 John Orange clemts 465 8
4 Dave Orange wichit 451 14
My problem is that I want the highscore table to display the top 20 users with the highest score, not the 20 highest scores.
Like this:
Rank---Name--------County------Score---Time
1 John Orange clemts 641 13
2 Dave Orange wichit 567 10
Need som help with this, not familiar with joining tables ;-)
This approach will show the top 20 users and each user's highest score, and if they have multiple instances of the same score, it'll show the information for the earliest one (lowest time value for that user and score).
SELECT *
FROM game_log gl
INNER JOIN users u
ON gl.user_ID = u.ID
INNER JOIN county c
ON u.countyid = c.countyid
WHERE not exists (select 1
from game_log gl2
where gl2.user_id = gl.user_id
and gl2.score > gl.score)
and not exists (select 1
from game_log gl2
where gl2.user_id = gl.user_id
and gl2.time < gl.time
and gl2.score = gl.score)
ORDER BY gl.score DESC, gl.time LIMIT 20;
Without doing this, if the same user in the top 20 had the same score 2+ times, they would be listed 2+ times, and you would not get back 20 people by using LIMIT 20 because the same person would be taking up N rows out of that 20.
SQL Fiddle here showing data with a tie: http://sqlfiddle.com/#!2/0ac931/5/0
GROUP BY should do the job.
SELECT users.ID, users.name, county.countyname, MAX(game_log.score) AS score, game_log.time
FROM game_log
INNER JOIN users ON game_log.user_ID = users.ID
INNER JOIN county ON users.countyid = county.countyid
GROUP BY game_log.user_ID
ORDER BY game_log.score DESC, game_log.time
LIMIT 20;
Try it out with SQL Fiddle.
I would do this with the not exists approach to get the highest score for each user. The rest of the query is the same:
SELECT *
FROM game_log gl INNER JOIN
users u
ON gl.user_ID = u.ID INNER JOIN
county c
ON u.countyid = c.countyid
WHERE not exists (select 1
from game_log gl2
where gl2.user_id = gl.user_id and gl2.score > gl.score
)
ORDER BY gl.score DESC, gl.time
LIMIT 20;
The where clause is saying "keep this row if no other row for the same user has a higher score".
Another way to do this is with the aggregation approach:
SELECT *
FROM (select user_id, max(score) as maxscore
from game_log gl
group by user_id
) gl INNER JOIN
users u
ON gl.user_ID = u.ID INNER JOIN
county c
ON u.countyid = c.countyid
ORDER BY gl.maxscore DESC
LIMIT 20;
But this method loses the information about time. It is possible to include that, but it makes the query more complicated.

Categories