2011-11-23 15 views
6

Ruby 1.9.2/rails 3.1/wdrożyć na Heroku -> posgresqlwróci każdy n-ty wiersz z bazy danych przy użyciu ActiveRecord w szynach

Cześć, Gdy liczba wierszy odnoszących się do przedmiotu idzie na pewnej wysokości, ja zamiast tego chcą wycofać każdy n-ty rząd. Dzieje się tak dlatego, że wiersze są używane (częściowo) do wyświetlania danych dla wykresów, więc gdy liczba zwróconych wierszy przekroczy wartość 20, dobrze jest zwrócić co drugą, i tak dalej.

To pytanie wydawało się wskazać w dobrym kierunku: ActiveRecord Find - Skipping Records or Getting Every Nth Record

robi mod na wierszu numer ma sens, ale przy użyciu zasadniczo:

@widgetstats = self.widgetstats.find(:all,:conditions => 'MOD(ROW_NUMBER(),3) = 0 ') 

nie działa, zwraca błąd:

PGError: ERROR: window function call requires an OVER clause 

I każda próba rozwiązania tego z np. opierając moje NAD klauzuli składnię rzeczy widzę w odpowiedzi na to pytanie:

Row numbering in PostgreSQL

kończy się błędy składniowe i nie mogę uzyskać wynik.

Czy brakuje mi bardziej oczywistego sposobu sprawnego zwracania każdego n-tego zadania, czy jestem na dobrej drodze, aby uzyskać wskazówki na temat drogi? Oczywiście, zwrot wszystkich danych i późniejszy montaż w szynach jest możliwy, ale strasznie nieefektywny.

Dziękujemy!

Odpowiedz

7

myślę szukasz zapytania jak ten:

SELECT * FROM (SELECT widgetstats.*, row_number() OVER() AS rownum FROM widgetstats ORDER BY id) stats WHERE mod(rownum,3) = 0 

To jest trudne do zbudowania przy użyciu ActiveRecord, więc możesz być zmuszony do zrobienia czegoś takiego:

@widgetstats = self.widgetstats.find_by_sql(
    %{ 
    SELECT * FROM 
    (
     SELECT widgetstats.*, row_number() OVER() AS rownum FROM widgetstats ORDER BY id 
    ) AS stats 
    WHERE mod(rownum,3) = 0 
    } 
) 

Będziesz oczywiście chciał zmienić zamówioną wersję i dodać dowolne klauzule WHERE lub inne modyfikacje do swoich potrzeb.

2

Gdybym to rozwiązał, sam napisałbym SQL, podobnie jak SQL, z którym się łączyłeś. Można to zrobić z

my_model.connection.execute('...') 

lub po prostu numery identyfikacyjne i znalezienie przez id

ids = (1..30).step(2) 
my_model.where(id => ids) 
Powiązane problemy