2010-08-26 4 views
0

Community Service ТаблицаMysql запрос помощь с тем, где пункт

|student name (id in real table)|hours|year|event name (id in real table)| 
|Johnny Smith     | 5|2010|Beach Clean-up    | 
|Samantha Bee     | 3|2011|Daily Show Volunteering  | 
|Samantha Bee     | 2|2011|Daily Show Bake Sale   | 
|Bilbo Baggins     | 10|2011|The Shire Feast Setup  | 

Из этой таблицы я хотел бы следующий вывод:

Часы в 2011 году:

Johnny Smith: 0 (his hours are in 2010) 
Samantha Bee: 5 
Bilbo Baggins: 10 

Вот моя неудачная попытка:

mysql_query("select name, 
        sum(hours) 
        from community_service 
        where year = '2011' 
        or year is null 
        group by name"); 

I unde Я не знаю, как это сделать правильно.

Заранее благодарен!

Поскольку мой Simplied запрос кажется, путает людей, вот весь энчилада:

SELECT DISTINCT contacts.contactID, 
sum(hours) as hours, 
contacts.first, 
contacts.last, 
contacts.graduates 
from contacts 
left join comm_stud using (contactID) 
left join comm_svc using (csID) 
left join tbl_yeardiv on comm_svc.termID = tbl_yeardiv.yeardivID 
WHERE (year = '2010-11') 
group by contacts.contactID 

tbl_yeardiv содержит школьные термины, как осенний и весенний семестры. comm_stud присоединяет студентов к каждому событию comm_svc.

+0

Основываясь на том, что вы пытаетесь сделать, мне кажется, что эта база данных нуждается в редизайне. – Chris

+0

@ Крис, почему? – Nicolas78

+0

Почему бы не иметь стол для людей и таблицу обслуживания. Человек - это лицо, а информация о нем и ее таблице обслуживания - год/часы для данного года. В этой таблице выше, как вы предоставляете услугу в 2010 году и 2011 году без двух записей для этого человека. Кроме того, что происходит, когда 2 человека имеют одно и то же имя (требуется первичный ключ) и оба предоставляют услугу в том же году (предполагает необходимость в таблице услуг с функциональным ключом, ссылающимся на таблицу лиц)? – Chris

ответ

1

Вы не хотите group by name?

Если вы хотите, нулевые значения, чтобы выглядеть хорошо, присоединиться к таблице против себя:

SELECT a.name, sum(b.hours) 
from community_service a 
LEFT OUTER JOIN 
community_service b 
on a.name = b.name 
WHERE b.year = 2011 
GROUP BY a.name 

Если в ваших реальных приложениях у вас есть несколько таблиц, вы просто LEFT OUTER JOIN usertable на стол ID-ЧАС-YEAR ,

+0

Обычно этот подход работает. То, что я получаю в ответ, - это таблица людей, у которых есть часы в 2011 году или люди, у которых нет часов. Те, у кого есть часы в другие годы, не включаются в список. Я посмотрю на это еще немного. Похоже, то, что вы написали, должно работать. Благодаря! – Stephane

0

попробуйте isnull(years). Кроме того, вам не нужно sum, если у вас не более одной записи на одного учащегося и год (если вы это делаете, вы можете использовать только sum, если вы также group by name, year). Наконец, почему год является строкой, то есть почему вы ставите вокруг него апострофы?

Если ни одна из этих проблем не поможет, пожалуйста, обновите свое сообщение спецификацией того, что точно не работает.

+0

Использование '2010', даже если год был int (а не строкой), будет по-прежнему правильно оцениваться. Я использую его по привычке и не думаю о типе данных в таблице. – Chris

+0

Если по какой-либо причине переменная задана неправильно, ошибки могут сильно разорвать страницу, а не возвращать пустые данные. Я предпочитаю последнее. Может быть, есть лучший способ. – Stephane

0

sum(hours), hours будет в порядке.

select name, 
     hours 
from community_service 
where year = '2011' 
+0

Спасибо, я уточнил запрос больше. – Stephane

0

Решение на самом деле довольно просто. Это связано с добавлением условия в предложение ON. От: http://opensourceanalytics.com/2006/07/29/advanced-mysql-join-tips-tricks/

Теперь предположим, что вы хотите искать не со всей таблицы2, а из поднабора таблицы2 (например, CityID = 1). Как ты это делаешь? Вы можете попробовать и посмотреть на себя, что следующий SQL не является решение:

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id 
WHERE table2.id IS NULL 
and table2.CityID = 1 

Обратите внимание, что это происходит потому, что мы ищем записи, которые не существуют в table2 и, следовательно, не может иметь где пункт о данных TABLE2.

Прочитайте страницу руководства немного дальше, а другой пользователь комментарий указывает:

Conditions for the “right table” go in the ON clause. 
Conditions for the “left table” go in the WHERE clause, 
except for the joining conditions themselves. 

Это делает решение, как:

SELECT table1.* FROM table1 LEFT JOIN table2 ON (table1.id=table2.id and table2.CityID = 1) 
WHERE table2.id IS NULL 

Таким образом, решение моего первоначального запроса выглядит примерно так это: (проверено работает запрос)

SELECT DISTINCT contacts.contactID, 
sum(hours) as hours, 
contacts.first, 
contacts.last, 
contacts.graduates from contacts 
left join comm_stud using (contactID) 
left join comm_svc using (csID) 

(Это секретный соус :)

left join tbl_yeardiv on (comm_svc.termID = tbl_yeardiv.yeardivID && year = '".thisyear()."') 

left join group_members on contacts.contactID = group_members.contactID 
left join groups using (groupID) 
WHERE groups.name = 'Students' 
and group_members.status like '%Matriculated%' 
group by contacts.contactID 

Спасибо за вашу помощь. Я надеюсь, что то, что я нашел, поможет вам легче писать запросы.

Смежные вопросы