GTFS MySQL Query Column Not Found - php

Im working with GTFS dataset that I have imported into MySql, Im accessing it with PHP.
Im trying to find the trips for a specific route for a given time and date.
My Sql query looks like this
'SELECT t.route_id AS route_id, t.service_id AS service_id, t.trip_headsign AS trip_headsign,
t.trip_id AS trip_id,
( SELECT departure_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY departure_time ASC limit 1) AS initial_departure_time,
( SELECT arrival_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY arrival_time DESC limit 1) AS final_arrival_time
FROM trips AS t INNER JOIN calendar_dates AS c
WHERE t.service_id = c.service_id
AND c.date ='.$calendar_date.'
AND initial_departure_time <='.$time.'
AND'.$time. '<=final_arrival_time
AND t.route_id ='.$route.'
ORDER BY trip_id ASC';
$route, $calendar_date and $time are all passed in.
The query is returning Column not found:
1054 Unknown column 'initial_departure_time' in 'where clause'. Im thinking that initial_departure_time cant be evaluated.
Im completely lost as too how to resolve this. Any clues, thanks in advance

You can't use aliases in your WHERE clause.
Either incorporate the sub-queries into the WHERE clause:
'SELECT t.route_id AS route_id,
t.service_id AS service_id,
t.trip_headsign AS trip_headsign,
t.trip_id AS trip_id,
(SELECT departure_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY departure_time ASC limit 1) AS initial_departure_time,
(SELECT arrival_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY arrival_time DESC limit 1) AS final_arrival_time
FROM trips AS t INNER JOIN calendar_dates AS c
WHERE t.service_id = c.service_id
AND c.date ='.$calendar_date.'
AND (SELECT departure_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY departure_time ASC limit 1) <='.$time.'
AND'.$time. '<= (SELECT arrival_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY arrival_time DESC limit 1)
AND t.route_id ='.$route.'
ORDER BY trip_id ASC';
Or wrap the query and then use the aliases in that:
'SELECT * FROM (
SELECT t.route_id AS route_id,
t.service_id AS service_id,
t.trip_headsign AS trip_headsign,
t.trip_id AS trip_id,
(SELECT departure_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY departure_time ASC limit 1) AS initial_departure_time,
(SELECT arrival_time
FROM stop_times
WHERE trip_id = t.trip_id
ORDER BY arrival_time DESC limit 1) AS final_arrival_time
FROM trips AS t INNER JOIN calendar_dates AS c
WHERE t.service_id = c.service_id
AND c.date ='.$calendar_date.'
AND t.route_id ='.$route.'
ORDER BY trip_id ASC) a
WHERE a.initial_departure_time <='.$time.'
AND'.$time. '<= a.final_arrival_time';
This might speed it up (you may need to swap the MIN and MAX around):
'SELECT t.route_id AS route_id,
t.service_id AS service_id,
t.trip_headsign AS trip_headsign,
t.trip_id AS trip_id,
MIN(s.departure_time) AS initial_departure_time,
MAX(s.arrival_time) AS final_arrival_time
FROM trips AS t
INNER JOIN calendar_dates AS c ON t.service_id = c.service_id
LEFT JOIN stop_times s ON s.trip_id = t.trip_id
WHERE c.date ='.$calendar_date.'
AND t.route_id ='.$route.'
GROUP BY t.route_id, t.service_id, t.trip_headsign, t.trip_id,
HAVING '.$time.' BETWEEN MAX(s.arrival_time) AND MIN(s.departure_time)
ORDER BY trip_id ASC';

Related

Need to use left join with limit but it works wrong

I have two sql query:
1)
SELECT DISTINCT item_id
FROM sh_itemviews WHERE login='".$login."'
ORDER by time DESC LIMIT 5"
2)
SELECT *
FROM sh_item WHERE id=itemIdFrom sh_itemviews "
So i want to do it better and i'm trying to use LEFT JOIN:
SELECT DISTINCT *
FROM sh_itemviews
LEFT JOIN sh_item ON sh_item.id = sh_itemviews.item_id;
WHERE sh_itemviews.login='".$login."'
ORDER by sh_itemviews.time DESC LIMIT 5"
Like a result i have all data where sh_item.id = sh_itemviews.item_id; but other constructin WHERE is ignored.
What i'm doing wrong?
Thanks!
You have a semicolon just before the WHERE statement.
"SELECT DISTINCT * FROM sh_itemviews LEFT JOIN sh_item ON sh_item.id = sh_itemviews.item_id**;** WHERE sh_itemviews.login='".$login."' ORDER by sh_itemviews.time DESC LIMIT 5"
The correct one is:
"SELECT DISTINCT *
FROM sh_itemviews
LEFT JOIN sh_item ON sh_item.id = sh_itemviews.item_id
WHERE sh_itemviews.login='".$login."'
ORDER by sh_itemviews.time DESC
LIMIT 5"
Extra semi column before the WHERE clause was the reason, Find the updated query below
SELECT DISTINCT *
FROM sh_itemviews
LEFT JOIN sh_item ON sh_item.id = sh_itemviews.item_id
WHERE sh_itemviews.login='".$login."'
ORDER by sh_itemviews.time DESC LIMIT 5"
You make incorrect syntax before where
Try this syntax
SELECT DISTINCT *
FROM sh_itemviews
LEFT JOIN sh_item ON sh_item.id = sh_itemviews.item_id
WHERE sh_itemviews.login='".$login."'
ORDER by sh_itemviews.time DESC
LIMIT 5"

How can I get the latest item price in mysql query?

I manage to get the lowest, highest and average price of the item but couldn't get the latest price. Below is the select query i am using by joining the item and item_price tables. How can I fix the problem?
$sql = 'SELECT *, MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price WHERE ip_price_date = "latest_date") AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
can you try following query:
$sql = 'SELECT *, MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price order by ip_price_date desc limit 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
Thanks #ahmet kamaran. It's working for my case here. I also replace * with those columns needed as suggested by others. So, after some testing from the above suggestions, here is my codes which retrieve those data i needed.
$sql = 'SELECT it_id, it_code, it_name, it_desc,
ip_id, ip_item_id, ip_supp_id, ip_price, ip_price_date, ip_ref_no, ip_remarks,
MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price ORDER BY ip_price_date DESC LIMIT 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1 AND cnf_item_price.ip_supp_id=?
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC';
$stmt = $DB->prepare($sql);
$stmt->bindValue(1,$supplier_id);
$stmt->execute();
http://sqlfiddle.com/#!9/ca6234/2
Thanks.
SELECT it_id, it_code, it_name, it_desc,
ip_id, ip_item_id, ip_supp_id, ip_price, ip_price_date, ip_ref_no, ip_remarks,
MIN(ip_price) AS lowest_price, MAX(ip_price) AS highest_price,
AVG(ip_price) AS average_price, MAX(ip_price_date) AS latest_date,
(SELECT ip_price FROM cnf_item_price WHERE cnf_item_price.ip_item_id = cnf_item.it_id
ORDER BY ip_price_date DESC LIMIT 1) AS latest_price
FROM cnf_item
INNER JOIN cnf_item_price ON cnf_item_price.ip_item_id = cnf_item.it_id
WHERE 1
GROUP BY cnf_item.it_id
ORDER BY cnf_item.it_name ASC;

can't find where this error ocur

SELECT e.emp_id, concat(e.firstname,' ', e.middlename,' ',e.lastname) as EmployeeName ,
(select * from mst_attendance where status='Present' AND a.current_date > '#2008-09-29%#' GROUP BY substr('emp_id',0,5) HAVING COUNT(*)>1 ORDER BY a.emp_id='5') as PresentDays,
a.emp_id, a.current_date, a.status, a.in_time, a.out_time FROM mst_attendance a
INNER JOIN mst_employee e ON a.emp_id=e.emp_id where e.status='active'
and e.flag='Y' and e.role='employee' and e.emp_id='5' ORDER BY a.created asc LIMIT 1
Here I want to know the present days of an employee. But I get the error:
1241 - Operand should contain 1 column(s)..
Instead of
(select * from mst_attendance where status='Present' AND a.current_date > '#2008-09-29%#' GROUP BY substr('emp_id',0,5) HAVING COUNT(*)>1 ORDER BY a.emp_id='5') as PresentDays
The query should be something like
(select column_name from mst_attendance where status='Present' AND a.current_date > '#2008-09-29%#' GROUP BY substr('emp_id',0,5) HAVING COUNT(*)>1 ORDER BY a.emp_id='5') as PresentDays

simple order by clause not working with inner join

this query is simply not ordering results the way i want it to:
$sql = mysql_query("select s.*, p.label, p.number
from `sales` as s
left join `pumps` as p on (p.id = s.id_pump)
where s.the_date >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 DAY))
order by CAST(s.amount_sale AS int) desc
limit 1") or die(mysql_error());
i am getting a mysql error.
Try casting the VARCHAR to a signed integer:
$sql = mysql_query("select s.*, p.label, p.number
from `sales` as s
left join `pumps` as p on (p.id = s.id_pump)
where s.the_date >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 DAY))
order by CAST(s.amount_sale AS SIGNED) desc
limit 1");

Ordering by posts in another table

I have created a feature where users can start new topics (similar to forums).
At the moment on a page, the query for the topics are as follows:
$q = "SELECT ".TBL_COMMUNITYTHREADS.".title, ".TBL_COMMUNITYTHREADS.".id,
".TBL_COMMUNITYTHREADS.".date, ".TBL_COMMUNITYTHREADS.".author, ".TBL_USERS.".username FROM ".TBL_COMMUNITYTHREADS."
INNER JOIN ".TBL_USERS." ON ".TBL_COMMUNITYTHREADS.".author = ".TBL_USERS.".id
WHERE type = '$type'
ORDER BY date DESC LIMIT $offset, $rowsperpage ";
The tables are constants and the offset and rowsperpage are variables passed in to limit how many posts are on a page.
At the moment though, all the topics are ordered by the date.
I want them to be ordered by the latest response.
Similarly to forums, when the reponse inside the topic is newest, that topic will go to the top.
The topics are stored in tbl_communitythreads and the replies in tbl_communityreplies.
How can I ordered them by the latest repsonse.
They are linked by the threadid in tbl_communityreplies. Also in that one is the date column.
Thankyou for reading, I just cant think of how to do this.
This:
SELECT c.title, c.id, c.date, c.author, u.username,
(
SELECT MAX(reply_date)
FROM tbl_communityreplies cr
WHERE cr.thread = c.id
) AS last_reply
FROM TBL_COMMUNITYTHREADS c
JOIN TBL_USERS u
ON u.id = c.author
ORDER BY
last_reply DESC, c.id DESC
LIMIT $offset, $rowsperpage
or this:
SELECT c.title, c.id, c.date, c.author, u.username
FROM (
SELECT cr.thread, cr.reply_date, cr.id
FROM tbl_communityreplies cr
WHERE (cr.last_reply, cr.id) =
(
SELECT last_reply, id
FROM tbl_communityreplies cri
WHERE cri.thread = cr.thread
ORDER BY
thread DESC, last_reply DESC, id DESC
)
ORDER BY
last_reply DESC, id DESC
LIMIT $offset, $rowsperpage
) q
JOIN TBL_COMMUNITYTHREADS c
ON c.id = q.thread
JOIN TBL_USERS u
ON u.id = c.author
ORDER BY
q.reply_date DESC, q.id DESC
The former query is more efficient for large values of $offset, or if you have few threads with lots of replies.
Issue the following commands:
CREATE INDEX ix_communitythreads_replydate_id ON TBL_COMMUNITYTHREADS (reply_date, id)
CREATE INDEX ix_communitythreads_thread_replydate_id ON TBL_COMMUNITYTHREADS (thread, reply_date, id)
for this to work fast.
by join with another table , then you can order by column from this table.

Categories