2013-07-26 11 views
7

Sto seguendo il tut di Bate sui grafici & ma sto riscontrando un errore.Rails: devono apparire nella clausola GROUP BY o essere utilizzati in una funzione aggregata

Questo è l'errore che sto ricevendo

PG::Error: ERROR: column "orders.created_at" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT created_at, sum(amount) as total_amount FROM "orders"... 
      ^
: SELECT created_at, sum(amount) as total_amount FROM "orders" WHERE ("orders"."created_at" BETW 

E questo è il codice che sto utilizzando nel mio Ordini modello

def self.total_grouped_by_day(start) 
    orders = where(created_at: start.beginning_of_day..Time.zone.now)#.all 
    orders = orders.group("date(created_at)") 
    orders = orders.select("date(created_at), sum(amount) as total_amount") 
    orders.group_by { |order| order.created_at.to_date } 
    end 

e nel mio aiutante

def orders_chart_data 
     orders_by_day = Order.total_grouped_by_day(3.weeks.ago) 
     (3.weeks.ago.to_date..Date.today).map do |date| 
      { 
       created_at: date, 
       price: orders_by_day[date].first.try(:total_amount) || 0 
      } 
     end 
    end 

Sto usando Postgres (che sono abbastanza sicuro è il motivo principale per cui ho riscontrato questo errore) & Rails 3.x.x. Perché si verifica questo errore & come si risolve?

Grazie in anticipo


Nella mia console:

Order.where(created_at: 3.weeks.ago.beginning_of_day..Time.zone.now).group("date(created_at)").select("date(created_at), sum(amount) as total_amount") 

& questo è ciò che ottengo

[#<Order >, #<Order >, #<Order >] 

strano ..


l'esecuzione di questo nella mia console: Order.where(created_at: 3.weeks.ago.beginning_of_day..Time.zone.now).group("date(created_at)").select("date(created_at), sum(amount) as total_amount").first.total_amount

mi dà questo:

Creating scope :page. Overwriting existing method Order.page. 
    Order Load (18.1ms) SELECT date(created_at), sum(amount) as total_amount FROM "orders" WHERE ("orders"."created_at" BETWEEN '2013-07-05 00:00:00.000000' AND '2013-07-26 23:50:38.876609') GROUP BY date(created_at) LIMIT 1 
=> "10.0" 

risposta

6

si esegue il raggruppamento date(created_at) ma non selezionando quella colonna. Modificare questa linea:

orders = orders.select("created_at, sum(amount) as total_amount") 

a questo:

orders = orders.select("date(created_at), sum(amount) as total_amount") 

che sarà anche tradursi in una modifica group_by della riga successiva pure.

Da uno dei miei progetti, utilizzando attributi leggermente diversi, ma facendo la stessa cosa di te:

1.9.3p327 > User.group('date(created_at)').select('date(created_at), sum(id) as total_amount').first.attributes 
    User Load (1.2ms) SELECT date(created_at), sum(id) as total_amount FROM "users" GROUP BY date(created_at) LIMIT 1 
=> {"date"=>"2011-09-27", "total_amount"=>"657"} 
+0

in realtà ho provato questo in un primo momento, ma sto ottenendo questo errore 'manca attributo: created_at' – goo

+0

Ottenere tale errore nella riga successiva group_by? Desideri. Hai bisogno di guardare a cosa stai tornando prima di fare quel group_by perché probabilmente non è più quello che vuoi. Ricorda, hai perfezionato la selezione in modo che la colonna non venga più restituita. –

+0

Giusto, quindi dovrei cambiarlo in 'orders.group_by {| order | order.date (created_at) .to_date} 'giusto? Non sono sicuro perché dopo averlo fatto, ottengo la variabile locale non definita o il metodo 'created_at 'per # goo

1

Un cast ad oggi sarebbe più semplice & più veloce. Qui il raw SQL dal momento che non sono esperto con la sintassi di Ruby (e nessun fan degli ORM che macellano SQL in generale).

SELECT created_at::date, sum(amount) AS total_amount 
FROM orders 
WHERE created_at ... 
GROUP BY created_at::date 
ORDER BY created_at::date 
Problemi correlati