Home All Groups Group Topic Archive Search About

SQL Statement for limiting the number of detail retrieved in Access 2000?

Author
23 Sep 2006 8:30 PM
Hexman
Hello All,

How do I limit the number of detail records selected  in a Master-Detail set using SQL?

I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
been trying with "TOP 3", but can't get anywhere.  Using Access 2000.

Something like:

SELECT  t1.*, TOP 3 t2.*
FROM t1, t2
WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)

Any help appreciated,

Hexman

Author
23 Sep 2006 11:17 PM
Izzy
Try this: (Or something of the like)

SELECT     t1.*, t3.*
FROM        t1
INNER JOIN
(SELECT TOP 3 t2.*
FROM              t2) t3 ON t1.Item = t3.Item
WHERE     (t1.TrnDate = #09/23/06#)

You may even want too use a LEFT OUTER JOIN for this, depends on your
data.

Izzy

Hexman wrote:
Show quoteHide quote
> Hello All,
>
> How do I limit the number of detail records selected  in a Master-Detail set using SQL?
>
> I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
>
> Something like:
>
> SELECT  t1.*, TOP 3 t2.*
> FROM t1, t2
> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
>
> Any help appreciated,
>
> Hexman
Author
25 Sep 2006 7:35 AM
Hexman
Izzy,

Thanks for the response.  I still can't get it to work, either with Access or SS EE.  It generates no error during execution, but doesn't return any
rows.  If I take out the "(SELECT TOP 3  t2.* FROM t2)"  and change all "t3" references to "t2", it retrieves the rows (except too many of them).

This has me stumped.  Any further ideas?

All I want to do is limit the number of rows returned from t2 to be joined with t1.

Thanks,

Hexman


Show quoteHide quote
On 23 Sep 2006 16:17:22 -0700, "Izzy" <israel.rich***@gmail.com> wrote:

>Try this: (Or something of the like)
>
>SELECT     t1.*, t3.*
>FROM        t1
>INNER JOIN
>(SELECT TOP 3 t2.*
> FROM              t2) t3 ON t1.Item = t3.Item
>WHERE     (t1.TrnDate = #09/23/06#)
>
>You may even want too use a LEFT OUTER JOIN for this, depends on your
>data.
>
>Izzy
>
>Hexman wrote:
>> Hello All,
>>
>> How do I limit the number of detail records selected  in a Master-Detail set using SQL?
>>
>> I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
>> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
>>
>> Something like:
>>
>> SELECT  t1.*, TOP 3 t2.*
>> FROM t1, t2
>> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
>>
>> Any help appreciated,
>>
>> Hexman
Author
25 Sep 2006 12:45 PM
Pritcham
Hi

I don't think you're going to be able to do this as the "Top x" clause
is going to limit your resultset to x number of records, not x number
of records for each 'grouping' (i.e. the link between your two tables)
so no matter how you try to link the results of this subquery to your
master table, you're only ever (at best) going to get x records from
the subquery.

Cheers
Martin

Hexman wrote:
Show quoteHide quote
> Izzy,
>
> Thanks for the response.  I still can't get it to work, either with Access or SS EE.  It generates no error during execution, but doesn't return any
> rows.  If I take out the "(SELECT TOP 3  t2.* FROM t2)"  and change all "t3" references to "t2", it retrieves the rows (except too many of them).
>
> This has me stumped.  Any further ideas?
>
> All I want to do is limit the number of rows returned from t2 to be joined with t1.
>
> Thanks,
>
> Hexman
>
>
> On 23 Sep 2006 16:17:22 -0700, "Izzy" <israel.rich***@gmail.com> wrote:
>
> >Try this: (Or something of the like)
> >
> >SELECT     t1.*, t3.*
> >FROM        t1
> >INNER JOIN
> >(SELECT TOP 3 t2.*
> > FROM              t2) t3 ON t1.Item = t3.Item
> >WHERE     (t1.TrnDate = #09/23/06#)
> >
> >You may even want too use a LEFT OUTER JOIN for this, depends on your
> >data.
> >
> >Izzy
> >
> >Hexman wrote:
> >> Hello All,
> >>
> >> How do I limit the number of detail records selected  in a Master-Detail set using SQL?
> >>
> >> I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
> >> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
> >>
> >> Something like:
> >>
> >> SELECT  t1.*, TOP 3 t2.*
> >> FROM t1, t2
> >> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
> >>
> >> Any help appreciated,
> >>
> >> Hexman
Author
25 Sep 2006 1:03 PM
Izzy
Martin is right, this cannot be handled in a query.

This will need to be handled in application code.

The only way this would work in a query is if the only 1 record was
returned by t1.

Izzy


Pritcham wrote:
Show quoteHide quote
> Hi
>
> I don't think you're going to be able to do this as the "Top x" clause
> is going to limit your resultset to x number of records, not x number
> of records for each 'grouping' (i.e. the link between your two tables)
> so no matter how you try to link the results of this subquery to your
> master table, you're only ever (at best) going to get x records from
> the subquery.
>
> Cheers
> Martin
>
> Hexman wrote:
> > Izzy,
> >
> > Thanks for the response.  I still can't get it to work, either with Access or SS EE.  It generates no error during execution, but doesn't return any
> > rows.  If I take out the "(SELECT TOP 3  t2.* FROM t2)"  and change all "t3" references to "t2", it retrieves the rows (except too many of them).
> >
> > This has me stumped.  Any further ideas?
> >
> > All I want to do is limit the number of rows returned from t2 to be joined with t1.
> >
> > Thanks,
> >
> > Hexman
> >
> >
> > On 23 Sep 2006 16:17:22 -0700, "Izzy" <israel.rich***@gmail.com> wrote:
> >
> > >Try this: (Or something of the like)
> > >
> > >SELECT     t1.*, t3.*
> > >FROM        t1
> > >INNER JOIN
> > >(SELECT TOP 3 t2.*
> > > FROM              t2) t3 ON t1.Item = t3.Item
> > >WHERE     (t1.TrnDate = #09/23/06#)
> > >
> > >You may even want too use a LEFT OUTER JOIN for this, depends on your
> > >data.
> > >
> > >Izzy
> > >
> > >Hexman wrote:
> > >> Hello All,
> > >>
> > >> How do I limit the number of detail records selected  in a Master-Detail set using SQL?
> > >>
> > >> I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
> > >> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
> > >>
> > >> Something like:
> > >>
> > >> SELECT  t1.*, TOP 3 t2.*
> > >> FROM t1, t2
> > >> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
> > >>
> > >> Any help appreciated,
> > >>
> > >> Hexman
Author
26 Sep 2006 3:44 AM
Hexman
OK, I understand. 

Can anyone give an code example of what Izzy suggests??

Thanks,

Hexman


Show quoteHide quote
On 25 Sep 2006 06:03:29 -0700, "Izzy" <israel.rich***@gmail.com> wrote:

>Martin is right, this cannot be handled in a query.
>
>This will need to be handled in application code.
>
>The only way this would work in a query is if the only 1 record was
>returned by t1.
>
>Izzy
>
>
>Pritcham wrote:
>> Hi
>>
>> I don't think you're going to be able to do this as the "Top x" clause
>> is going to limit your resultset to x number of records, not x number
>> of records for each 'grouping' (i.e. the link between your two tables)
>> so no matter how you try to link the results of this subquery to your
>> master table, you're only ever (at best) going to get x records from
>> the subquery.
>>
>> Cheers
>> Martin
>>
>> Hexman wrote:
>> > Izzy,
>> >
>> > Thanks for the response.  I still can't get it to work, either with Access or SS EE.  It generates no error during execution, but doesn't return any
>> > rows.  If I take out the "(SELECT TOP 3  t2.* FROM t2)"  and change all "t3" references to "t2", it retrieves the rows (except too many of them).
>> >
>> > This has me stumped.  Any further ideas?
>> >
>> > All I want to do is limit the number of rows returned from t2 to be joined with t1.
>> >
>> > Thanks,
>> >
>> > Hexman
>> >
>> >
>> > On 23 Sep 2006 16:17:22 -0700, "Izzy" <israel.rich***@gmail.com> wrote:
>> >
>> > >Try this: (Or something of the like)
>> > >
>> > >SELECT     t1.*, t3.*
>> > >FROM        t1
>> > >INNER JOIN
>> > >(SELECT TOP 3 t2.*
>> > > FROM              t2) t3 ON t1.Item = t3.Item
>> > >WHERE     (t1.TrnDate = #09/23/06#)
>> > >
>> > >You may even want too use a LEFT OUTER JOIN for this, depends on your
>> > >data.
>> > >
>> > >Izzy
>> > >
>> > >Hexman wrote:
>> > >> Hello All,
>> > >>
>> > >> How do I limit the number of detail records selected  in a Master-Detail set using SQL?
>> > >>
>> > >> I want to select all master records for a date, but only the first 3 records for the details (based on the primary key of the detail record).  I've
>> > >> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
>> > >>
>> > >> Something like:
>> > >>
>> > >> SELECT  t1.*, TOP 3 t2.*
>> > >> FROM t1, t2
>> > >> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
>> > >>
>> > >> Any help appreciated,
>> > >>
>> > >> Hexman
Author
25 Sep 2006 12:38 PM
C-Services Holland b.v.
Hexman wrote:
> Hello All,
>
> How do I limit the number of detail records selected  in a
Master-Detail set using SQL?
>
> I want to select all master records for a date, but only the first 3
records for the details (based on the primary key of the detail record).
  I've
> been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
>
> Something like:
>
> SELECT  t1.*, TOP 3 t2.*
> FROM t1, t2
> WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
>
> Any help appreciated,
>
> Hexman

You need to understand what you're doing before you can optimize it :)
Now you're creating a dataset that effectively creates a copy of all
records in t2 for each entry in t1. If you have alot of records, this
will get ouf of hand very quickly (i.e. 2 tables with 1000 records each
will cause 10.000 records in memory this way) So using a join like Izzy
suggested is usually much better.

How about this:

Select *
from t1 inner join t2 on (t1.item=t2.item)
where t1.TrnDate=#09/23/06#
and t2.item in
(select top 3 item from t2)

This should join the 2 tables where the 'item' in the 2 tables match and
the date in t1 is the one specified and the items appear in the top 3 of
t2. There is no sort order given to t2, so results may be unpredictable.


--
Rinze van Huizen
C-Services Holland b.v
Author
25 Sep 2006 2:36 PM
Pritcham
Hi Rinze

You're absolutely right - I was trying to think of how to limit the
result set in the detail selection before the join happened and
completely missed the use of IN() along with a subquery.  I knew I
should have waiting longer before posting!

As for performance on this - as you say, it sucks! Mainly because, as
far as I understand, it's running the subquery for each and every row
in the resultset.

Having just ran a quick test on a couple of handy tables I have here
(only returning 1500 rows in the end results) and the performance was
way too slow to be acceptable for me so depending on the need I think
I'd probably just do a straight join and then limit the number that I
display client-side (again, depending on the volume of data that's got
to travel the wire and how frequently etc).

Still - at least I can cross "learn something new today" off my TODO
list!

Martin
C-Services Holland b.v. wrote:
Show quoteHide quote
> Hexman wrote:
>  > Hello All,
>  >
>  > How do I limit the number of detail records selected  in a
> Master-Detail set using SQL?
>  >
>  > I want to select all master records for a date, but only the first 3
> records for the details (based on the primary key of the detail record).
>   I've
>  > been trying with "TOP 3", but can't get anywhere.  Using Access 2000.
>  >
>  > Something like:
>  >
>  > SELECT  t1.*, TOP 3 t2.*
>  > FROM t1, t2
>  > WHERE (t1.item = t2.item)  AND  (t1.TrnDate = #09/23/06#)
>  >
>  > Any help appreciated,
>  >
>  > Hexman
>
> You need to understand what you're doing before you can optimize it :)
> Now you're creating a dataset that effectively creates a copy of all
> records in t2 for each entry in t1. If you have alot of records, this
> will get ouf of hand very quickly (i.e. 2 tables with 1000 records each
> will cause 10.000 records in memory this way) So using a join like Izzy
> suggested is usually much better.
>
> How about this:
>
> Select *
> from t1 inner join t2 on (t1.item=t2.item)
> where t1.TrnDate=#09/23/06#
> and t2.item in
> (select top 3 item from t2)
>
> This should join the 2 tables where the 'item' in the 2 tables match and
> the date in t1 is the one specified and the items appear in the top 3 of
> t2. There is no sort order given to t2, so results may be unpredictable.
>
>
> --
> Rinze van Huizen
> C-Services Holland b.v