Joe, it seems to me all you need is this part here:
select course, event_code, min(finals) as "min_time" from times
    where id_competitor=XXXX and finals>0
    group by course, event_code

Or are you interested in returning other columns within the 'times' table?
if so, just use min(other columns) in the query, no need for a derived 
table.

So, in any case, web2py works a little differently. Taking the book example 
and modifying it, here's what I get...

for row in db(db.times.competitor==xxxx).select(
        db.times.course, db.times.event_code, min_time, 
groupby=(db.times.course,db.times.event_code)):
        print row.times.course, row[min_time]

What you need to do before that can work is to create the min_time 
operator...

min_time = db.times.finals.min()

oh, but you wanted to only select non negative numbers, and finals has some 
negatives in it...  (add a where clause to the select)
Good luck!

On Monday, February 17, 2014 2:46:23 PM UTC-7, Joe Barnhart wrote:
>
> Hi Richard --
>
> Don't need to try it...  Do a thought experiment...  The "belongs" matches 
> the entire set of all affected times, event_codes and courses.  It becomes 
> the cartesian product of all combinations of time, event_code, and course. 
>  It matches N*M*K entries in the times table, where N, M, and K are the 
> counts of the members of the set.  By contrast, the number of rows in the 
> minimum times query is a tiny fraction of that.
>
> Let's say I have a competitor with a minimum time of 10 sec. in event 1, 
> course A.  He may also have that exact time (on a bad day) for event 2, 
> course B.  In this scenario, event 2 course B would normally be a much 
> faster time -- in fact his "best" times has such a faster time.  But when 
> you do the overall query with "belongs" on ALL members of times, 
> event_code, and course, you will match BOTH 10 sec. times -- event 1 on 
> course A and event 2 on course B, so both times will appear in the final 
> result.  (Along with the true best time for event 2, course B, which was 
> faster than 10 sec.)
>
> I could probably do a correlated subquery to solve this problem, but those 
> are famously inefficient.  The join, convoluted as it is (and I agree 
> there) is still the best way.
>
> What I really wish I could do is use a select to return the min(time) and 
> the ID of the row it occurred on.  But GROUP BY won't allow that.  One of 
> the limitations of the set theory underpinning SQL.  That's where the 
> correlated subquery comes it -- do a select with ORDER BY on time, then 
> choose LIMIT BY 0,1 to get only one row.  But that query has to be repeated 
> for every combination of course and event_code.  I have about 20 rows to 
> search for a typical competitor and each query above takes around 700 ms. 
> so that's not a good option!
>
> -- Joe B.
>
> On Monday, February 17, 2014 12:51:07 PM UTC-8, Richard wrote:
>>
>> But what you do in the join should be reproducible in a where clause... I 
>> start rewriting your join into a where clause at first and realize that I 
>> would need to rewrite 3-4 for time the same subquery in sql or I had to 
>> write a recursive query that would not help in translation into web2py 
>> query...
>>
>> I don't see how the multiples belongs would not lead to the samething as 
>> you query did you try it?
>>
>> You still have the option of just using db.executesql(''' your actual sql 
>> query ''')
>>
>> Richard
>>
>>
>> On Mon, Feb 17, 2014 at 3:24 PM, Joe Barnhart <joe.ba...@gmail.com>wrote:
>>
>>> Hi Richard --
>>>
>>> I thought about a subquery...  But I've never seen or heard of the trick 
>>> of using "subquery[0]" to pick out one column of the subquery.  
>>>
>>> I see your approach is to materialize the subquery as a Rows object and 
>>> then pick out elements.  I don't think this will work as expected tho 
>>> because the "belongs" logic will choose incorrect values.  For example say 
>>> the time is 10 seconds, but there are 20 different rows (NOT "best" times) 
>>> with the same time.  Your approach will choose the 10 sec. time for ALL 
>>> combinations of event code and course -- not just the SPECIFIC combination 
>>> in the row that matches the "best" time..  
>>>
>>> That's why I chose a "join" -- it forces the elements to match 
>>> perfectly.  But thanks for the technique.  The idea of materializing the 
>>> Rows and using it in another query bears thinking about.
>>>
>>> -- Joe
>>>
>>>
>>> On Monday, February 17, 2014 7:32:57 AM UTC-8, Richard wrote:
>>>
>>>> Hello Joe,
>>>>
>>>> Found your plain sql query already convoluted, there is not simpler way 
>>>> to express it in SQL first? You seem to use join as if it was a where, 
>>>> join 
>>>> not intent for this, using it like that will make thing slower...
>>>>
>>>> Could this work :
>>>>
>>>> subquery = db.executesql('''select course, event_code, min(finals) as "
>>>> min_time" from times
>>>>     where id_competitor=XXXX and finals>0
>>>>     group by course, event_code''')
>>>>
>>>> rows = db((db.times.event_code.belongs(subquery[1])) & (db.times.
>>>> course.belongs(subquery[0]) & (db.times.min_time.belongs(subquery[2])) 
>>>> & (db.times.competitor=='XXXX').select(db.times.ALL)
>>>>
>>>> I can't try 
>>>>
>>>> :(
>>>>
>>>> Richard
>>>>
>>>>
>>>> On Mon, Feb 17, 2014 at 6:38 AM, Joe Barnhart <joe.ba...@gmail.com>wrote:
>>>>
>>>>> So I'm trying to use the DAL to create all of my queries, but I may 
>>>>> have just exceeded its capability.
>>>>>
>>>>> My task is to create a view of "best times" for a particular sport. 
>>>>>  The sport has multiple events and the user is interested in collecting 
>>>>> their best times over the entire database, organized by event.  The SQL 
>>>>> looks something like this:
>>>>>
>>>>> select * from times as t
>>>>> inner join (
>>>>>   select course, event_code, min(finals) as "min_time" from times
>>>>>     where id_competitor=XXXX and finals>0
>>>>>     group by course, event_code
>>>>>   ) as tt
>>>>> on t.event_code=tt.event_code
>>>>>   and t.course=tt.course
>>>>>   and t.finals=tt.min_time
>>>>>   and t.id_competitor=XXXX
>>>>> order by t.course, t.event_code
>>>>>
>>>>> The XXXX represents a specific literal ID number for the competitor. 
>>>>>  This query is to be run for each competitor when they choose to see the 
>>>>> view, so limiting it to a single person is the desired approach.  
>>>>>
>>>>> The inner join choose the best (minimum) time for each course and 
>>>>> event_code.  
>>>>>
>>>>> Disqualifications are stored as negative times, so the clause to 
>>>>> restrict finals>0 is to exclude any of these outliers.
>>>>>
>>>>> I've been studying up on the alternate join syntax for the DAL but I 
>>>>> don't see a way to handle the conditions such as "finals>0" in the new 
>>>>> syntax.  If the "on" method could be attached to a Set object instead of 
>>>>> only a Table, maybe I could approach this query.
>>>>>
>>>>> But I thought I'd ask the real SQL experts before I give up.  Also, 
>>>>> what is my fallback if I need to do this query outside of DAL?
>>>>>
>>>>> -- Joe B.
>>>>>
>>>>>  -- 
>>>>> Resources:
>>>>> - http://web2py.com
>>>>> - http://web2py.com/book (Documentation)
>>>>> - http://github.com/web2py/web2py (Source code)
>>>>> - https://code.google.com/p/web2py/issues/list (Report Issues)
>>>>> --- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "web2py-users" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to web2py+un...@googlegroups.com.
>>>>>
>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>>
>>>>
>>>>  -- 
>>> Resources:
>>> - http://web2py.com
>>> - http://web2py.com/book (Documentation)
>>> - http://github.com/web2py/web2py (Source code)
>>> - https://code.google.com/p/web2py/issues/list (Report Issues)
>>> --- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "web2py-users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to web2py+un...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>
>>
>>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to