Как лучше составить SQL запрос?

Пытаюсь сделать хороший, нормально читаемый SQL запрос для базы следующего вида:

Таблицы:
users [id, name] // больше полей для примера не нужно
users_events [id, timestamp, event_type, event_value, user_id]
users_data [id, timestamp, data_name, data_value, user_id]

В users_events добавляются данные после каждого события у пользователя. Пример события: смена места жительства.
Выглядит как:
{ 
  id: 123, 
  timestamp: '10.03.13', 
  event_type: 'city',
  event_value: 'Moscow', 
  user_id: '888'
}


В users_data хранятся параметры пользователей, например — Имя пользователя (и если оно сменится, то старая запись останется, а последняя будет использоваться и данные из нее будут выводиться). Другой пример — Номера телефонов. Вот их может быть несколько и все могут быть активные.
{
  id:122,
  timestamp: , // некая дата
  data_name: 'last_name',
  data_value: 'Vasechkin', // сначала было старое имя
  user_id: 888
}
{
  id:123,
  timestamp: , // некая дата
  data_name: 'last_name',
  data_value: 'Pupkin', // потом заменили на новое
  user_id: 888
}
{
  id:124,
  timestamp: , // некая дата
  data_name: 'phone',
  data_value: '1234567',
  user_id: 888
}
{
  id:125,
  timestamp: , // некая дата
  data_name: 'phone',
  data_value: '1233214',
  user_id: 888
}



Собственно, какой нужен запрос:
Нужно выбирать из базы таких пользователей, у которых последнее место жительства, например, 'Moscow', а также активное (последнее) имя LIKE %pup% и, в добавок, в одном из номеров есть цифра 7

+ нужно подсчитать количество записей в базе (на join'ах мой COUNT() почему-то ломался).

Сразу скажу, что довольно важна читаемость и доделываемость. Будет просто супер, если запрос впишется в API баз CodeIgnitter'a

PS: Следует упомянуть то, что переделывать структуру базы — не вариант, так как она активно используется и там куча данных, которые никак нельзя терять.
  • Вопрос задан
  • 3717 просмотров
Решения вопроса 1
@Sayonji
Ничего лучше, кроме как в лоб, не придумывается.
select users.* from users

inner join user_events cities on users.id = cities.user_id
inner join
(select max(e.id) id, user_id from user_events e where event_type='city' group by user_id)
cities_fresh on cities_fresh.id = cities.id

inner join user_data names on users.id = names.id
inner join
(select max(d.id) id, user_id from user_data d where data_name='last_name' group by user_id)
names_fresh on names_fresh.id = names.id

inner join user_data phones on user.id = phones.user_id

where phone like '%7%' and city = 'Moscow' and last_name like '%uti%'

В общем, я бы пересмотрел ваше решение не перестраивать базу. Ничего не потеряется, просто добавьте новые таблицы с актуальными данными и поставьте для них триггеры или что там.
А еще можете свой запрос выложить, если он проще. Я не придумал.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы