Mysql запрос справки с предложением где

0

Таблица услуг сообщества

|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"); 

Я понимаю, почему 'year 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 
WHERE (year = '2010-11') 
group by contacts.contactID 

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

  • 0
    Исходя из того, что вы пытаетесь сделать, мне кажется, что эта база данных нуждается в редизайне.
  • 0
    @ Крис, почему это?
Показать ещё 4 комментария
Теги:
where-clause

4 ответа

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 применимы к таблице ID-HOUR-YEAR.

  • 0
    Обычно такой подход работает. В ответ я получаю таблицу людей, у которых есть часы в 2011 году, ИЛИ люди, у которых нет часов. Те, у кого есть часы в другие годы, не включены в список. Я посмотрю на это еще немного. Кажется, то, что вы написали, должно работать. Спасибо!
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

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

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

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 

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

0

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

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

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

Вам не нужно sum(hours), hours будет в порядке.

select name,
       hours 
from community_service 
where year = '2011'
  • 0
    Спасибо, я уточнил запрос больше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню