Count workers in business with branches - php

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
)

Related

SQL Query with two different filters

I have a page which shows all cars from DB.
I have two filters , both are multiple select filter.
For example
filter 1 - Color
Red , green , blue <-- All these are checkbox ,can be selected multiple
filter 2 - brand
BMW, Honda , Hyundai <-- All these are checkbox ,can be selected multiple
I have done below query
Select * from cars
JOIN term_car_relationships
ON cars.id = term_cars_relationships.car_id
WHERE term_cars_relationships.term_id in (6,2,3)
GROUP BY cars.id
In above query term_id
6 = blue (Color)
2 = green (Color)
3 = BNW (brand)
But with above query I will get all cars which has blue color or green color or BMW brand
But how to change in such a way that I get BMW which is blue or green color.
I have 3 tables which handles these categories.
taxonomy table
taxonomy_id | taxonomy_title
1 | Color
2 | Brand
term_list
term_id | term_name | taxonomy_id
1 | Blue | 1
2 | Red | 1
3 | BMW | 2
4 | Honda | 2
term_cars_relationships Table
term_id | car_id
1 | 1
1 | 2
2 | 3
You should join the term_cars_relationships table twice:
SELECT * FROM cars
JOIN term_car_relationships c ON cars.id = c.car_id
JOIN term_car_relationships b ON cars.id = b.car_id
WHERE c.type_of_category = 'color'
AND b.type_of_category = 'brand'
AND c.term_id in (6,2)
AND b.term_id in (3)
GROUP BY cars.id
Note that I used b.term_id in (3) instead of b.term_id = 3 since I assumed you might want to select multiple brands.
You can construct your query with separate joins for each term category, and separate filter conditions for each as well.
SELECT cars.*, colorTerms.*, brandTerms.*
FROM cars
INNER JOIN term_car_relationships AS carColorTerms
ON cars.id = carColorTerms.car_id
INNER JOIN term_list AS colorTerms
ON carColorTerms.term_id = colorTerms.term_id AND colorTerms.taxonomy_id = 1
INNER JOIN term_car_relationships AS carBrandTerms
ON cars.id = carBrandTerms.car_id
INNER JOIN term_list AS brandTerms
ON carBrandTerms.term_id = brandTerms.term_id AND brandTerms.taxonomy_id = 2
WHERE colorTerms.term_id IN (6, 2)
AND brandTerms.term_id IN (3)
Of course, to construct this query, you will need to know the terms' types before the query.
Also, using GROUP BY cars.id without aggregation is probably a sign of a problem, or just not the right way to get what you want. If you only want the information from the cars table, you should just SELECT DISTINCT cars.*. Using GROUP BY in this manner will end up with results with the data from just one color-brand match for each car.
With the complexity the edit to the original question added, another possibility presents itself....
SELECT cars.* -- You should really just select the fields you want, and may have to in some configurations (see GROUP BY)
FROM cars AS c
INNER JOIN term_car_relationships AS tcr ON c.car_id = tcr.car_id
INNER JOIN term_list AS tl ON tcr.term_id = tl.term_id
WHERE tcr.term_id IN (6, 2, 3)
GROUP BY cars.car_id -- In some configurations of MySQL, and most other RDBMSes, you must specify every SELECTed non-aggregated field here
HAVING COUNT(DISTINCT tl.taxonomy_id)
= ( SELECT COUNT(DISTINCT taxonomy_id)
FROM term_list
WHERE term_id IN (6, 2, 3)
)
Note: This final solution does not actually require you to know term taxonomies ahead of time anymore, and does not grow as more taxonomies need supported; so while it is a little less obvious with what it is doing, is probably definitely worth considering.

Need Mysql Query for Search Bus from stop and To Stop

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`

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.

MySql Select Result Having Combined Multiple Queries From Both the Same Table and Others

I have a table ('names') which includes data related with other data in other tables relying on ids. For example:
*Names table
id | name | predecessor | successor | house | birthplace
-----------------------------------------------------------------
10 Bayezid II 9 11 4 NULL
11 Selim I 10 12 4 5
12 Suleiman 11 13 4 61
*Houses table
id | house
--------------
4 House of Osman
*Places table
id | place
--------------
5 Amasya
61 Trabzon
What I'm trying to accomplish is to construct a query which results in returning whole information depending on the id, like:
{"result":[{
"id":"11",
"name":"Selim I",
"predecessor": "Bayezid II",
"successor": "Suleiman",
"house":"House of Osman",
"birthplace":"Amasya"
}]}
So, the name of the house and the birthplace are brought from other tables ('houses', 'places') whereas the predecessor and the successor are from the same table. I need help constructing this query. Thank you.
Just self-join a couple times, once to get the predecessor's row (aliased n0 below), and once more for the successor's (n2):
SELECT n1.id, n1.name, n0.name AS predecessor, n2.name AS successor
FROM names n1
LEFT JOIN names n0 ON n1.predecessor = n0.id
LEFT JOIN names n2 ON n1.successor = n2.id
SQL Fiddle demo
Joining to get the house and birthplace are left as an exercise for the reader.
Try this:
select n.id,
n.name,
n1.name as predecessor,
n2.name as successor,
h.house,
p.place
from names n
inner join names n1 on n.id = n1.predecessor
inner join names n2 on n.id = n2.successor
left join Houses h on n.house = h.id
left join Place p on n.birthplace = p.id
where n.id = 11

Result display problem in php and mysql

A B C
P_id | name | add P_id | t_id t_id | paper
----------------- -------------- ------------------
1 sam ca 1 1 1 asdxa
2 john de 2 1 2 dgfv
3 sam jk 3 2 3 decgf
4 sam ca 4 3 4 ergvtr
Now I can easily make a search for Name 'sam' in Table A group by name, add. and It shows me result like,
sam ca
sam jk
I am using php and mysql. I want to do some additional task in this:-
--> Totalcount for the rows..Like
sam ca 2
sam jk 1
(I am not taking P_id here... just focus on name and add.)
--> Make a link on 2 and 1 (above). so if I click on it. It should displays the related papers on another html page from table C.
example: if I click on 2... then it should display asdxa and decgf.
--> Totalcount for the rows..Like
SELECT `name`, `add`, count(`add`) FROM `A` WHERE (`name` = 'sam') GROUP BY `add`;
As for the linking, you just link to the page with that ID, and have your php script get the data from the given id in the C table.
To select all matching occurences while searching for a name:
SELECT `A`.`name` AS name, `A`.`P_id` AS aid, `C`.`t_id` AS cid, `C`.`paper` AS paper
FROM `A` , `C`
WHERE (
`A`.`name` = 'sam'
)
AND (
`A`.`P_id` = `C`.`t_id`
)
result:
name aid cid paper
sam 1 1 qwertyui
sam 3 3 zxcvbn
sam 4 4 uytrewq
sam 5 5 hfdsa
Which matches the test tables I did in my local environment
Try to use for the first task
$pdo = new PDO(....);
$result = $pdo->query('SELECT name, add, count(*) from table where name='sam' group by add;')->fetchAll();
if ($result) {
foreach($result as $row) {
......
}
}
//second
$sql = 'select paper from tableA a inner join TableB b on a.P_id=b.P_id inner join Tablec c inner join b.t_id = c.t_id where a.p_id=2';
//repeat previous statements

Categories