W jaki sposób zrobiłbyś to zapytanie podrzędne Rails używając Squeela?

Chcę zrestrukturyzować poniższe zapytanie za pomocą Squeel. Chciałbym to zrobić, aby móc połączyć łańcuchy operatorów i ponownie użyć logiki w różnych częściach zapytania.

User.find_by_sql("SELECT 
    users.*,
    users.computed_metric,
    users.age_in_seconds,
    ( users.computed_metric / age_in_seconds) as compound_computed_metric
    from
    (
      select
        users.*,
        (users.id *2 ) as computed_metric,
        (extract(epoch from now()) - extract(epoch from users.created_at) ) as age_in_seconds
        from users
    ) as users")

Zapytanie musi działać w DB i nie powinno być hybrydowym rozwiązaniem Ruby, ponieważ musi zamawiać i kroić miliony rekordów.

Ustawiłem problem tak, aby działał normalnieuser stół i abyś mógł grać z alternatywami do niego.

Ograniczenia dotyczące akceptowalnej odpowiedzizapytanie powinno zwrócić aUser obiekt ze wszystkimi normalnymi atrybutamikażdy obiekt użytkownika powinien również zawieraćextra_metric_we_care_about, age_in_seconds icompound_computed_metriczapytanie nie powinno powielać żadnej logiki, po prostu wypisując ciąg w wielu miejscach - chcę uniknąć dwukrotnego wykonywania tego samego[zaktualizowane] Zapytanie powinno być możliwe w DB, aby zestaw wyników, który może składać się z milionów rekordów, mógł zostać zamówiony i pocięty w DB przed powrotem do Rails[zaktualizowane] Rozwiązanie powinno działać dla DB PostgresPrzykład typu rozwiązania, które chciałbym

Poniższe rozwiązanie nie działa, ale pokazuje typ elegancji, który mam nadzieję osiągnąć

class User < ActiveRecord::Base
# this doesn't work - it just illustrates what I want to achieve

  def self.w_all_additional_metrics
    select{ ['*', 
              computed_metric, 
              age_in_seconds, 
              (computed_metric / age_in_seconds).as(compound_computed_metric)] 
      }.from{ User.w.compound_computed_metric.w_age_in_seconds }
  end

  def self.w_computed_metric
    where{ '(id *2 ) as computed_metric' }
  end

  def self.w_age_in_seconds
    where{ '(extract(epoch from now()) - extract(epoch from created_at) ) as age_in_seconds' }
  end
end
Powinieneś być w stanie uruchomić to w oparciu o istniejącą bazę danych

Pamiętaj, że nieco opracowałem problem, abyś mógł korzystać z istniejącegoUser klasa i baw się nią w konsoli.

EDYTOWAĆDB, którego używam, to Postgres.Nie jestem pewien, czy w 100% wyjaśniłem, że zapytanie powinno zostać wykonane w DB. Nie może być odpowiedzią hybrydową, ponieważ część logiki jest zasadniczo wykonywana w Railsach. Jest to ważne, ponieważ chcę mieć możliwość porządkowania i dzielenia milionów rekordów za pomocą obliczonych kolumn.

questionAnswers(3)

yourAnswerToTheQuestion