Вложенные запросы в Arel

Я пытаюсь вложить Запросы Select в Arel и/или Active Record в направляющих 3 для генерации следующего SQL-оператора.

SELECT sorted.* FROM (SELECT * FROM points ORDER BY points.timestamp DESC) AS sorted GROUP BY sorted.client_id

Псевдоним для подзапроса может быть создан путем выполнения

points = Table(:points)
sorted = points.order('timestamp DESC').alias

но затем я застреваю как, как передать его в родительский запрос (за исключением вызова #to_sql, который звучит довольно ужасным).

Как Вы используете оператор SELECT в качестве подзапроса в Arel (или Активная Запись) для выполнения вышеупомянутого? Возможно, существует в целом другой способ выполнить этот запрос, который не использует вложенные запросы?

19
задан Schrockwell 24 May 2010 в 04:57
поделиться

1 ответ

Вопрос в том, зачем вам нужен «вложенный запрос»? Нам не нужно использовать «вложенные запросы», как думают в мышлении SQL, а не реляционной алгебры. С помощью реляционной алгебры мы выводим отношения и используем выходные данные одного отношения в качестве входных данных для другого, так что справедливо следующее:

points = Table(:points, {:as => 'sorted'}) # rename in the options hash
final_points = points.order('timestamp DESC').group(:client_id, :timestamp).project(:client_id, :timestamp)

Лучше всего, если мы оставим переименование в arel, если только это не будет абсолютно необходимо.

Здесь ОЧЕНЬ важна проекция client_id И timestamp, поскольку мы не можем спроецировать все домены из отношения (т.е. отсортированные. *). Вы должны специально спроектировать все домены, которые будут использоваться в операции группирования для отношения. Причина в том, что для * нет значения, которое четко представляло бы сгруппированный client_id. Например, у вас есть следующая таблица

client_id   |   score
----------------------
    4       |    27
    3       |    35
    2       |    22
    4       |    69

Здесь, если вы группируете, вы не можете выполнить проекцию в области оценки, потому что значение может быть 27 или 69, но вы можете спроецировать сумму (оценку)

Вы можете только проецировать атрибуты домена, которые имеют уникальные значения для группы (которые обычно являются агрегатными функциями, такими как sum, max, min). С вашим запросом не имеет значения, были ли точки отсортированы по метке времени, потому что в конце они будут сгруппированы по client_id. порядок отметок времени не имеет значения, поскольку не существует единой отметки времени, которая могла бы представлять группу.

Пожалуйста, дайте мне знать, как я могу помочь вам с Арел. Кроме того, я работал над серией обучающих программ, чтобы люди могли использовать Arel в своей основе. Первая из серии находится на http://Innovative-Studios.com/#pilot . Я могу сказать, что вы начинаете понимать, как это делать, поскольку вы использовали Table (: points), а не модель ActiveRecord Point.

8
ответ дан 30 November 2019 в 02:48
поделиться
Другие вопросы по тегам:

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