Inner Join problems PHP - php

I have three tables: bound, station and time
Bound has 2 columns: boundID and boundName
Station has 3 columns: stationID stationName boundID
Time has 4 columns: timeID departureTime tramID stationID
I am wanting to display the startStation and endStation the user enters into the form and display the time if the stations entered by the user in the textfields have the same boundID. Currently, this is all I have managed to do and can't seem to get a result. Any help would be greatly appreciated!
//display tram times from one station to another
ELSE if($startStation != '' && $endStation !='' && $DepartureTime =='' && $DepartureTime2 =='')
$query ="SELECT b.boundName, s.stationName, t.departureTime
FROM Station s, Time t, Bound b
INNER JOIN Bound b
ON S.boundID=B.boundID
WHERE s.stationName = '$startStation'AND'$endStation'";
I get this message when I try this: "Not unique table/alias: 'b'"
This is an example of the data I have:
stationID stationName boundID
5 | CitySquare | 2 ________________________________________________________________________________
boundID boundName
2 | South-Southbound ________________________________________________________________________________
timeID departureTime tramID stationID
1 | 07:18:00 | 1 | 5
The expected result is the user is able to insert a startStartion and an endStation and obtain the departure time, if the boundID are the same.
This is the result I want to output
Bound Name | Start Station | End Station | Departure Time
South-SouthBound | Stourton | CitySquare | 09:49:00

Try changing your query to something like below:
SELECT b.boundName as bond_name, s.stationName as station_name, t.departureTime as departure_time
FROM Station as s, Time as t, Bound as b
INNER JOIN Bound as b
ON s.boundID = b.boundID
WHERE s.stationName = '$startStation' AND s.stationName = '$endStation'

Change the below portion of code
INNER JOIN Bound b
with
INNER JOIN Bound c
and change the alias names of the columns too. There are too same alias assignment found in your query
It will make confusion while compile the query. Mysql cound not understand which table you are referring to.
Edit:
Try with the below code. I am not sure which table have the "boundID" field
$query ="SELECT b.boundName, s.stationName, t.departureTime
FROM Station s, Time t, Bound b
INNER JOIN Bound c
ON s.boundID=b.boundID
WHERE s.stationName = '$startStation'AND'$endStation'";

Your DB schema is a bit weird to me. From my point of view you are missing a lot of necessary data columns in your tables.
But just to get your expected result you can try this query:
http://sqlfiddle.com/#!9/e5ef0/1
SELECT
b.boundName `Bound Name`,
s.stationName `Start Station`,
e.stationName `End Station`,
t.departureTime `Departure Time`
FROM station s
INNER JOIN station e
ON e.boundId = s.boundId
AND e.stationName='$endStation'
INNER JOIN bound b
ON b.boundId=s.boundId
INNER JOIN `time` t
ON t.stationId=s.stationId
WHERE s.stationName = '$startStation'

Related

How to join and sum a column in two tables based on another column using mysqli and php (just using query)

I have 2 tables about blood bank:
donates
orders
in donates table I have 2 fields showing how many donations we have:
------------------------
| blood_group | amount |
------------------------
| A+ | 2 |
| B- | 3 |
| O+ | 4 |
| A+ | 3 |
| O+ | 1 |
in orders table I have 2 column that how many requests we submit based on blood group:
------------------------
| blood_group | amount |
------------------------
| A+ | 4 |
| B- | 3 |
| O+ | 4 |
| AB- | 6 |
My problem is I want to use mysqli query to get an array that show me this result based on these conditions:
show how many we need group by blood_group
if we don't need any blood_group or we don't have any request for that blood type show zero (not showing null)
not showing negative number for our blood shortage
I manage to do this so far:
<?php
$con = mysqli_connect("localhost", "root", "", "test");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql ="SELECT donates.blood_group as blood_group,
donates.amount as donates_amount,
orders.amount as orders_amount,
FROM `donates`
LEFT JOIN `orders`
ON donates.blood_group = orders.blood_group
GROUP BY donates.blood_group";
// Perform queries
$result = mysqli_query($con, $sql);
if (!$result = mysqli_query($con, $sql)) {
echo "SQLSTATE error: " . mysqli_sqlstate($con);
echo "<br>";
echo "SQLSTATE error: " . mysqli_error($con);
exit;
}
$result = mysqli_fetch_all($result, MYSQLI_ASSOC);
var_dump($result);
mysqli_close($con);
That query shows me sum of blood_groups but here is the main question:
So here are the main questions:
how to subtract (donates_amount and orders_amount)
how to make them positive (subtract which one first)
how to show the result even if one blood group is not presented on the other (full join)
Use union all and group by:
select blood_group, sum(donate_amount) as donate_amount,
sum(order_amount) as order_amount
from ((select blood_group, amount as donate_amount, 0 as order_amount
from donates
) union all
(select blood_group, 0 as donate_amount, amount as order_amount
from orders
)
) od
group by blood_group;
The only caveat is that a blood group needs to be in one of the tables. If you have a separate table of all of them, you should use that. For instance:
select bg.*,
coalesce(donate_amount, 0) as donate_amount,
coalesce(order_amount, 0) as order_amount
from blood_groups bg left join
(select blood_group, sum(amount) as donate_amount
from donates
group by blood_group
) d
on d.blood_group = bg.blood_group left join
(select blood_group, sum(amount) as order_amount
from donates
group by blood_group
) o
on o.blood_group = bg.blood_group ;
In either of these queries, you can get the difference using - and show negative numbers as 0 using greatest(). For instance:
greatest(sum(donate_amount) - sum(order_amount), 0)
To answer your first question :
how to subtract (donates_amount and orders_amount)
You must use SUM() function with a minus sign:
SUM(donates.amount - orders.amount);
this will subtract the total sum of two tables
But we have some problem here: you may have null values (because you may not have some of the blood groups present in one of tables) that give the wrong result. you must change the null values to zero with COALESCE() function:
SUM(COALESCE(donates.amount,0) - COALESCE(orders.amount,0))
We must extra check if the result does not equal to null:
COALESCE(SUM(COALESCE(donates.amount,0) - COALESCE(orders.amount,0)),0)
how to make them positive (subtract which one first)
And at last if you want to avoid negative numbers you must use mysqli math functions named ABS() that give you absulute value:
ABS(COALESCE(SUM(COALESCE(donates.amount,0) - COALESCE(orders.amount,0)),0))
so your query will look like this:
$sql = "SELECT donates.blood_group as blood_group,
COALESCE(donates.amount,0) as donates_amount,
COALESCE(orders.amount,0) as orders_amount,
ABS(COALESCE(SUM(COALESCE(donates.amount,0) - COALESCE(orders.amount,0)),0)) as needed_amount
FROM `donates`
LEFT JOIN `orders`
ON donates.blood_group = orders.blood_group
GROUP BY donates.blood_group";
how to show the result even if one blood group is not presented on
the other (full join)
In order to make full join you must use union with the invers form of your query. so that you find other records in orders table and unite the results into one results:
$sql = "SELECT donates.blood_group as blood_group,
COALESCE(donates.amount,0) as donates_amount,
COALESCE(orders.amount,0) as orders_amount,
ABS(COALESCE(SUM(COALESCE(donates.amount,0) - COALESCE(orders.amount,0)),0)) as needed_amount
FROM `donates`
LEFT JOIN `orders`
ON donates.blood_group = orders.blood_group
GROUP BY donates.blood_group
UNION
SELECT orders.blood_group as blood_group,
COALESCE(donates.amount,0) as donates_amount,
COALESCE(orders.amount,0) as orders_amount,
ABS(COALESCE(SUM(COALESCE(orders.amount,0) - COALESCE(donates.amount,0)),0)) as needed_amount
FROM `orders`
LEFT JOIN `donates`
ON orders.blood_group = donates.blood_group
GROUP BY orders.blood_group";

How to choose a value from another table using a JOIN

I just want to know one SQL query.
I've got two tables:
id | id_town
1 | 26
id | town
26 | Prague
What's the query if I need to print "Prague"?
Thank you.
PhpMyAdmin prints #1052 - Column 'id' in on clause is ambiguous
I tried this
SELECT town FROM localities JOIN towns ON id = id_town
TRY THIS:
select b.town
from table1 a
inner join table2 b on a.id_town = b.id

MySQL: Select several rows based on several keys from two different tables

I have these two tables - user_schedules and user_schedule_meta, shown below:
------------------------------------
| id | scheduler_id | status |
------------------------------------
1 3 pending
2 5 active
3 6 active
and
----------------------------------------------
| id | user_schedule_id | meta_key |meta_value
----------------------------------------------
1 3 course-id 135
2 3 session-id 15
3 3 schedule-id 120
I want to write a query to enable me select, for example, from both tables where EVERYONE of the below 5 conditions are met:
user_schedule_id = 3
scheduler_id = 6
session_id = 15
course-id = 135
schedule-id = 120
This is what I have so far, but it is not working:
SELECT user_schedule_meta.`id` FROM user_schedule_meta, user_schedules
WHERE user_schedules.`scheduler_id` = 6
AND user_schedules.id = user_schedule_meta.`user_schedule_id`
AND (
(user_schedule_meta.`meta_key` = 'course-id' AND user_schedule_meta.`meta_value` = 135)
OR (user_schedule_meta.`meta_key` = 'session-id' AND user_schedule_meta.`meta_value` = 15)
OR (user_schedule_meta.`meta_key` = 'daily-schedule-id' AND user_schedule_meta.`meta_value` = 120)
)
GROUP BY user_schedule_meta.`id`
Any suggestions what I am not doing right?
This is a typical key-value store lookup problem. These are trickier than they look in SQL, in that they require multiple JOIN operations.
You need a virtual table with one row per user_schedules.id value, then you can filter it. So
SELECT u.id, u.scheduler_id
FROM user_schedules u
JOIN user_schedule_meta a ON u.id=a.user_schedule_id AND a.meta_key='course-id'
JOIN user_schedule_meta b ON u.id=b.user_schedule_id AND b.meta_key='session-id'
JOIN user_schedule_meta c ON u.id=c.user_schedule_id AND c.meta_key='daily-schedule-id'
WHERE a.meta_value = 135 -- value associated with course-id
AND b.meta_value=15 -- value associated with session-id
AND c.meta_value=120 -- value associated with daily-schedule-id
Notice also that you can list your table with associated attributes like this. This trick of joining the key/value table multiple times is a kind of pivot operation. I use LEFT JOIN because it will allow the result set to show rows where an attribute is missing.
SELECT u.id, u.scheduler_id, u.status,
a.meta_value AS course_id,
b.meta_value AS session_id,
c.meta_value AS daily_schedule_id
FROM user_schedules u
LEFT JOIN user_schedule_meta a ON u.id=a.user_schedule_id AND a.meta_key='course-id'
LEFT JOIN user_schedule_meta b ON u.id=b.user_schedule_id AND b.meta_key='session-id'
LEFT JOIN user_schedule_meta c ON u.id=c.user_schedule_id AND c.meta_key='daily-schedule-id'
try this is code
select * from user_schedule_meta where user_schedule_id=3 and
(meta_key='session-id' AND meta_value=15
or meta_key='daily-schedule-id' AND meta_value=120
or meta_key='course-id' AND meta_value=135
)

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

MySQL selecting row for attendance case

I have these tables:
table 1 : attendance
-------------------------------
ID | DATE | EMPLOYEE_ID |
-------------------------------
1 2013-09-10 1
2 2013-09-10 2
3 2013-09-10 3
-------------------------------
table 2: employee
---------------
ID | NAME |
---------------
1 Smith
2 John
3 Mark
4 Kyle
5 Susan
6 Jim
---------------
My actual code to show employee option.
while($row=mysql_fetch_array($query)){
echo "<option value='$row[employee_id]'>$row[first_name] $row[last_name]</option>";
}
?>
How can i show the list of employee that not registered in table 1?
The condition is if an employee already registered in table 1, they won't appear on the option.
I want to show the list in <option>'s of <select> element. So it will return: kyle, susan, jim.
Please tell me the correct query or if there is any better option, it'll be good too. Please give some solution and explain. Thank you very much
UPDATE / EDIT:
it also based on current date, if in table 1 have no latest date e.g. today it's 2013-09-15. It will show all of employee.
You can do this with a left join and then checking for no matches:
select e.*
from employee e left outer join
attendance a
on e.id = a.employee_id
where a.employee_id is null;
This is probably the most efficient option in MySQL.
EDIT:
To include a particular date, add the condition to the on clause:
select e.*
from employee e left outer join
attendance a
on e.id = a.employee_id and a.date = date('2013-09-20')
where a.employee_id is null;
If I understood correctly this should work, get all employees whose ID is not in the attendance table.
SELECT * FROM employee WHERE employee.ID NOT IN
(SELECT EMPLOYEE_ID FROM attendance)

Categories