2013-04-24 5 views
0

У меня есть база данных sql и я использую php для доступа к ней.mySQL Query With Joins and Counts

Мои таблицы выглядит следующим образом:

Полеты Таблица полета ID, Время, Аэропорт

мест Таблица Flight ID, Номер места

У меня есть следующий запрос:

SELECT f.FlightID 'ID', Count(*) 'Seats Booked' FROM flights f, seats s GROUP BY f.FlightID 

Я хочу, чтобы быть

Flight ID мест Занято

ID Num мест книга

Проблема в настоящее время он показывает это:

[{"ID":"0","Seats Booked":"37"},{"ID":"1234","Seats Booked":"37"}] (The output is JSON encoded) 

Когда это должно быть быть как 10 и 27 если вы будете следовать за мной? Кажется, что это не соединение.

Пожалуйста, объясните, что я делаю неправильно, а не просто ответ.

Спасибо!

+1

Предложение: Пожалуйста, не используйте пробел по имени. –

ответ

3

LMC,

Вы не использовали положение, чтобы сделать соединение. Вот почему вы получили сумму за каждую сгруппированную инструкцию.

Правильная инструкция, используя синтаксис должен быть что-то вроде:

SELECT f.FlightID 'ID', Count(*) 'Seats Booked' 
FROM flights f, seats s 
where s.FlightId = f.FlightId 
GROUP BY f.FlightID 

Использование внутреннего соединения синтаксис должен быть чем-то вроде:

SELECT f.FlightID 'ID', Count(*) 'Seats Booked' 
FROM flights f 
inner join seats s 
on s.FlightId = f.FlightId 
GROUP BY f.FlightID 

Вы можете сделать что-то без использования таблицы полета. Полетный стол не имеет никакого значения, потому что вы возвращаете группу рейсида. И места для стола имеют рейд. Заявления ниже должно быть достаточно.Это верно, если вы не обеспокоены рейсами без забронированных мест

SELECT s.FlightID 'ID', Count(*) 'Seats Booked' 
FROM seats s 
GROUP BY s.FlightID 

Если вы хотите показать полеты без забронированных мест, то вы должны использовать левое соединение для полетов. Приведенное ниже решение решит эту проблему.

SELECT f.FlightID 'ID', Count(*) 'Seats Booked' 
FROM flights f 
left join seats s 
on s.FlightId = f.FlightId 
GROUP BY f.FlightID 
+0

Почему это лучше, чем внутренний запрос? Какие преформы лучше? – LmC

+0

Я отредактировал мое сообщение. Взгляните в последнем заявлении. Вам не нужно соединение, чтобы получить только забронированные рейсы и количество мест –

+0

@JoseAreas Если он хочет, чтобы места были забронированы с * всех * рейсов, тогда он хотел бы, чтобы JOIN обеспечил, чтобы он забирал места, забронированные только там, где существует FlightID в таблице рейсов –

1

Прежде всего, вы должны использовать синтаксис соединения, показанный ниже, поскольку ваш синтаксис несколько устарел. Во-вторых, не забудьте включить положение о where

SELECT f.FlightID 'ID', count(*) as "seat count" 
INNER JOIN seats s On 
f.FlightID = s.FlightID 
Where f.FlightID = 'some_id' 
GROUP BY f.FlightID 
+0

Ahh, я понял, так что это требует внутреннего запроса? Почему это? Можно ли это сделать без одного? Отличный ответ! – LmC

+0

@LmC Если вы не используете подзапрос, подсчет будет просто выбирать количество полных строк, возвращаемых * целым * запросом, и использовать их для каждой строки. –

+0

Так это лучший способ сделать это тогда? – LmC

1

Здесь проблема с вашим подходом является вы не присоединяющиеся таблиц. То, что я подразумеваю, присоединяется, это «Таблица 1» относится к «Таблице2» с некоторыми отношениями. В вашем случае это идентификатор полета. Поэтому в другой таблице (Таблица мест) вы будете иметь данные о местах, но это будет доступно для любого конкретного рейса. Поэтому для того, чтобы иметь соответствующие записи, вам нужно присоединиться к этим двум таблицам на основе рейса, чтобы вы получали разное количество мест для каждого рейса.

Пробуйте этот sql.

select f.flightid as 'id', count(s.seat_number) as seats_booked 
from flight f, seats s 
where f.flightid=s.flightid 
group by f.flightid 
+0

Почему это лучше, чем внутренний запрос? Какие преформы лучше? – LmC

+1

это ни лучше, ни хуже. Это просто альтернативный синтаксис, делает то же самое, что и внутреннее соединение. –

+0

@LmC: в любом выполнении sql-инструкции начинается снизу, а выбор строк происходит последним. Таким образом, в вашем решении, когда происходит выбор, выполняется другой sql. поэтому для выполнения потребуется больше времени. следует избегать такой практики. – ankurtr

2

Если вы ничего больше, чем Flight ID из таблицы полетов не нужно, почему бы не просто делать это:

ВЫБРАТЬ s.FlightID, COUNT (s.id) FROM меСт S GROUP BY s.FlightID

Если вам также необходимо рассчитать полеты без каких-либо мест, используйте:

ВЫБЕРИТЕ f.flightID, COUNT (с. id) ОТ полетов f LEFT JOIN seat s ON s.flightID = f.flightID GROUP BY f.flightID

+0

Потому что соединение выберет все места из таблицы сидений, где существует FlightID в таблице рейсов. –

+0

вы правы.Если нужны нулевые места, то используйте только соединение. Но внутреннее соединение не является решением для этого в любом случае –

+0

Я обновил свой ответ. LEFT JOIN следует использовать здесь, чтобы принимать во внимание полеты с 0 местами –