@@ -45,6 +45,10 @@ def taken_clause
4545 "TOP (#{ relation . taken . to_i } ) "
4646 end
4747
48+ def eager_limiting_select?
49+ single_distinct_select? && taken_only? && relation . group_clauses . blank?
50+ end
51+
4852 def single_distinct_select?
4953 relation . select_clauses . size == 1 && relation . select_clauses . first . include? ( 'DISTINCT' )
5054 end
@@ -87,10 +91,24 @@ def select_sql_without_skipped(windowed=false)
8791 groups = relation . group_clauses
8892 havings = relation . having_clauses
8993 orders = relation . order_clauses
90- select_clause = windowed ? selects . map { |sc | select_clause_without_expression ( sc ) } . join ( ', ' ) :
91- "SELECT #{ taken_clause if taken_only? } #{ selects . join ( ', ' ) } "
94+ if windowed
95+ selects = selects . map { |sc | select_clause_without_expression ( sc ) }
96+ elsif eager_limiting_select?
97+ groups = selects . map { |sc | select_clause_without_expression ( sc ) }
98+ selects = selects . map { |sc | "#{ taken_clause } #{ select_clause_without_expression ( sc ) } " }
99+ orders = orders . map do |oc |
100+ oc . split ( ',' ) . reject ( &:blank? ) . map do |c |
101+ max = c =~ /desc\s */i
102+ c = select_clause_without_expression ( c ) . sub ( /(asc|desc)/i , '' ) . strip
103+ max ? "MAX(#{ c } )" : "MIN(#{ c } )"
104+ end . join ( ', ' )
105+ end
106+ elsif taken_only?
107+ fsc = "#{ taken_clause } #{ selects . first } "
108+ selects = selects . tap { |sc | sc . shift ; sc . unshift ( fsc ) }
109+ end
92110 build_query (
93- select_clause ,
111+ ( windowed ? selects . join ( ', ' ) : "SELECT #{ selects . join ( ', ' ) } " ) ,
94112 "FROM #{ relation . from_clauses } " ,
95113 ( locked unless locked . blank? ) ,
96114 ( joins unless joins . blank? ) ,
0 commit comments