मैं कैसे पा सकते हैं एक संबद्ध तालिका में सबसे पुराने रिकॉर्ड को छानने के द्वारा यह गुण है?

0

सवाल

मैं मॉडल Subscription जो has_many Versionएस.

एक Version एक status, plan_id और authorized_at तारीख.

किए गए किसी भी परिवर्तन करने के लिए एक Subscription से आता है एक Version संशोधनों को अद्यतन यह माता पिता Subscription.

लक्ष्य खोजने के लिए है प्रत्येक सदस्यता के Version के साथ सबसे पुराना authorized_at तारीख WHERE के versions.plan_id के रूप में ही है subscriptions.plan_id (दूसरे शब्दों में, मैं की जरूरत है प्राधिकरण की तारीख Version जहां plan_id परिवर्तित करने के लिए वर्तमान Subscription's plan_id).

इस क्वेरी मैं के साथ आया हूँ. मैं एक त्रुटि हो रही में समेकित फ़ंक्शन सिंटैक्स:

syntax error at or near "MIN" LINE 3: MIN (authorized_at) from versions ^

क्वेरी:

select subscriptions.id,
MIN (authorized_at) from versions
where versions.plan_id = subscriptions.plan_id
) as current_version
from subscriptions
join versions on subscriptions.id = versions.subscription_id
where versions.status = 'processed'

मैं भी यकीन नहीं कर रहा हूँ अगर मैं किया जाना चाहिए समूहीकरण के संस्करणों के द्वारा plan_id और फिर से उठा । मैं कर रहा हूँ की तरह खो दिया है ।

database postgresql ruby ruby-on-rails
2021-11-23 14:26:06
3

सबसे अच्छा जवाब

1

आप उपयोग कर सकते हैं एक पार्श्व सबक्वेरी कर सकते हैं, जो सबसे अच्छा में वर्णित किया जा के रूप में एक foreach पाश में SQL. वे कर रहे हैं एक extremly performant तरह का चयन करने के लिए स्तंभों में से एक एकल संबंधित रिकॉर्ड या यहां तक कि समुच्चय के एक समूह से संबंधित रिकॉर्ड.

के लिए प्रत्येक पंक्ति में सदस्यता DB का चयन करेंगे एक एकल पंक्ति से संस्करणों के द्वारा आदेश दिया authorized_at:

SELECT "subscriptions".*,
       "latest_version"."authorized_at" AS current_version,
       "latest_version"."id" AS current_version_id -- could be very useful
FROM   "subscriptions" 
LATERAL
  (
     SELECT   "versions"."authorized_at", "versions"."id"
     FROM     "versions"
     WHERE    "versions"."subscription_id" = "subscriptions"."id" -- lateral reference
     AND      "versions"."plan_id" = "subscriptions"."plan_id"
     AND      "versions"."status" = 'processed'
     ORDER BY "versions"."authorized_at" ASC
     LIMIT 1
  ) latest_version ON TRUE

बनाने के पार्श्व में ActiveRecord किया जा सकता है के साथ या तो SQL तार या Arel:

class Subscription < ApplicationRecord
  # Performs a lateral join and selects the 
  # authorized_at of the latest version 
  def self.with_current_version
    lateral = Version.arel_table.then do |v|
      v.project(
        v[:authorized_at],
        v[:id] # optional
      ).where(
        v[:subscription_id].eq(arel_table[:id])
          .and(v[:plan_id].eq(arel_table[:plan_id]) )
          .and(v[:status].eq('processed'))
      )
      .order(v[:authorized_at].asc)
      .take(1) # limit 1
      .lateral('latest_version ON TRUE')
    end
    lv = Arel::Table.new(:latest_version) # just a table alias
    select(
      *where(nil).arel.projections, # selects everything previously selected
      lv[:authorized_at].as("current_version"),
      lv[:id].as("current_version_id") # optional
    ).joins(lateral.to_sql)
  end
end

अगर आप बस करने के लिए चाहते हैं का चयन करें id और current_version कॉलम आप चाहिए पर विचार का उपयोग कर बांधना चुनने के बजाय डेटाबेस मॉडल है कि कर रहे हैं नहीं ठीक तरह से हाइड्रेटेड.

2021-11-23 16:49:48
1

आप उपयोग कर सकते हैं DISTINCT ON बाहर फिल्टर करने के लिए पंक्तियों, और रखने के एक एकल के प्रति एक सदस्यता-पहली प्रति एक समूह के अनुसार ORDER BY खंड.

उदाहरण के लिए:

select distinct on (s.id) s.id, v.authorized_at
from subscription s
join versions v on v.subscription_id = s.id and v.plan_id = s.plan_id
where v.status = 'processed'
order by s.id, v.authorized_at
2021-11-23 16:40:51

धन्यवाद । क्वेरी लगता है में काम करने के लिए कंसोल, लेकिन जब मैं इसका इस्तेमाल करने की कोशिश में मेरे विचार के रूप में एक मॉडल के दायरे मैं ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near "WHERE" LINE 6: ...s.id, v.authorized_at WHERE "sub...
pinkfloyd90

@pinkfloyd90 मैं कोई विशेषज्ञ रहा हूँ पर ActiveRecord, लेकिन हो सकता है यह काम नहीं करता है, क्योंकि विचार है शायद नहीं updatable.
The Impaler
0

नीचे दिए गए कोड दे देंगे versions जहां संस्करण है plan_id बराबर है करने के लिए सदस्यता के plan_id.

@versions = Version.joins("LEFT JOIN subscriptions ON subscriptions.plan_id = versions.plan_id")

फिल्टर करने के लिए रिकॉर्ड संस्करण के status

@versions = Version.joins("LEFT JOIN subscriptions ON subscriptions.plan_id = versions.plan_id").where(status: "processed")

फिल्टर करने के लिए रिकॉर्ड संस्करण के status और आदेश द्वारा authorized_at आरोही क्रम में.

@versions = Version.joins("LEFT JOIN subscriptions ON subscriptions.plan_id = versions.plan_id").where(status: "processed").order(:authorized_at)

फिल्टर करने के लिए रिकॉर्ड संस्करण के status और आदेश द्वारा authorized_at में decending आदेश.

@versions = Version.joins("LEFT JOIN subscriptions ON subscriptions.plan_id = versions.plan_id").where(status: "processed").order(authorized_at: :desc)

आशा है कि यह तुम्हारे लिए काम करता है!

2021-11-23 14:33:48

मुझे लगता है कि आप की जरूरत है शामिल होने के लिए पर subscriptions.id = versions.subscription_id या आप मिल जाएगा के संस्करणों में परिणाम है कि संबंधित नहीं है कि है कि करने के लिए सदस्यता. तुम भी भी नहीं छुआ के कोर पर जो सवाल है, का चयन करने के लिए एक समग्र.
max

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में