473,385 Members | 1,492 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

How to select TOP X results of a field for each value of another field?

176 100+
Hello!

There's something that seems quite simple to do, but I still don't understand how to do it:

I need to create a query from the following table:

Table1:

P: Date: CountOfMeetings:
1 01/12 4
1 02/12 0
1 03/12 2
1 04/12 0
1 05/12 3
1 06/12 2
1 07/12 2
2 01/12 3
2 02/12 2
2 07/12 3
2 12/12 1
2 14/12 3
2 15/12 4
3 3/12 2
3 4/12 4
3 5/12 0
3 9/12 2
3 10/12 6
3 11/12 5

The query should take TOP 3 Dates for each P(person), so the result should be like the following:

P: Date: CountOfMeetings:
1 01/12 4
1 02/12 0
1 03/12 2
2 01/12 3
2 02/12 2
2 07/12 3
3 3/12 2
3 4/12 4
3 5/12 0

(The CountOfMeetings field is just an example field)

I appriciate your time.
May 2 '11 #1
11 2384
Rabbit
12,516 Expert Mod 8TB
You'll need to use a subquery. But even before you can use a subquery, you need to fix your data to support it. First off, you need a unique key of some sort, even if it's an autonumber. Second, your "date" field isn't a date, I can't figure out what format it is. Third, your "top 3" isn't top 3 of anything, it sounds more like you're looking for first 3 rather than top 3.
May 2 '11 #2
Michael R
176 100+
I have a unique key, my date is a real date, I just gave a simplified example in order not to overload with too much detail.
I need the 3 lowest dates.

How can I use the subquery in order to get the result?
May 3 '11 #3
Rabbit
12,516 Expert Mod 8TB
What you do is alias the table so that you can access it from the subquery. The subquery just needs to return the top 3 IDs sorted by your date so you cam select those IDs from the main query.
May 3 '11 #4
NeoPa
32,556 Expert Mod 16PB
Michael R:
I just gave a simplified example in order not to overload with too much detail.
We applaud you for your thinking, and for a question where obvious attempts have been made to pass the required info. Please bear in mind for future questions though, that short/unclear date information leads to ambiguity and potential confusion. Not a criticism, as clearly you've made efforts to be clear, but worth bearing in mind certainly.

Rabbit. I'm really rusty on this point (and I seem to recall it was you who first led me to understand some of the possibilities available for use in SQL subqueries). I tried out the SQL below and it prompted for tO.P on line #13. I've used slightly different field names than the question, but I think it's clear what does what. Would you possibly know where I've gone wrong here?

Expand|Select|Wrap|Line Numbers
  1. SELECT DISTINCT
  2.        tO.P
  3.      , sQ.Start
  4.      , sQ.CVal
  5. FROM   [Tbl1] AS tO
  6.        INNER JOIN
  7.        (
  8.     SELECT TOP 3
  9.              [P]
  10.            , [Start]
  11.            , [CVal]
  12.     FROM     [tbl1] AS tI
  13.     WHERE    (tI.P=tO.P)
  14.     ORDER BY [Start]
  15.        ) AS sQ
  16.   ON   tO.P=sQ.P
May 3 '11 #5
NeoPa
32,556 Expert Mod 16PB
Just to clarify my thinking here:

I believe subqueries in the FROM clause are only determined once. As such it doesn't make sense to me that they can take record-level parameters (tO.P changes for each record in tO ==> the subquery will not have access to these values, and couldn't be run again to produce different results on every change of tO.P anyway).

I cannot see a way for this to work with subqueries outside of the FROM clause. Here I'm on shaky ground as I know you've put forward solutions in this area before that I hadn't thought of. For now at least though, it seems to me this is not possible.
May 3 '11 #6
Rabbit
12,516 Expert Mod 8TB
That's probably why it's prompting for it. Because it's in the FROM clause. However, it may also be that the word TO is a reserved SQL key word.

However, I don't believe that SQL would return the results intended. Your subquery will only return the top 3 rather than top 3 per group even if it wasn't in the FROM clause.

There's two queries that can get the requested results.

Expand|Select|Wrap|Line Numbers
  1. SELECT GroupField, SortField, ValueField
  2. FROM Table1 Tout
  3. WHERE UniqueID IN (
  4.     SELECT TOP 3 UniqueID
  5.     FROM Table1 Tin
  6.     WHERE Tin.GroupField = Tout.GroupField
  7.     ORDER BY SortField
  8. )
  9.  
  10. SELECT TP.GroupField, TP.SortField, TP.ValueField
  11. FROM Table1 TP
  12. INNER JOIN Table1 TC ON TP.GroupField = TC.GroupField
  13.     AND TC.SortField <= TP.SortField
  14. GROUP BY TP.GroupField, TP.SortField, TP.ValueField
  15. HAVING COUNT(*) <= 3
I suspect, given proper indexes, the second query will run faster. But the first one is easier to understand.
May 3 '11 #7
NeoPa
32,556 Expert Mod 16PB
Impressed.
-NeoPa :-)

PS: It never occurred to me that tableOutside (or tO) might clash with TO :-D
I was getting reasonably inventive with my SQL for a while, but clearly I'm rusty. This is good stuff though. I particularly appreciate the second version. Less obvious (a bonus in itself) but also more efficient logically (even if, as you say, it's a little less intuitive to follow).
May 3 '11 #8
Rabbit
12,516 Expert Mod 8TB
The second query is a relatively new discovery. I found it while researching how to store dynamic hierarchies in databases. It was used to determine the depth of the nodes in the hierarchy but I've found it useful in other situations, especially when speed is a concern.
May 3 '11 #9
NeoPa
32,556 Expert Mod 16PB
Nice :-)

All we need now is to check that Michael can actually appreciate the concepts involved and reproduce this in his quesry. Let us know Michael.
May 3 '11 #10
ADezii
8,834 Expert 8TB
@Michael R - A Code Based solution should be relatively simple, I'll see what I come up with. At least it will give you another Option to work with.
May 3 '11 #11
ADezii
8,834 Expert 8TB
The following Code will produce the exact results that you are looking for, then write them to the Immediate Window. It does not require a Unique Key/Index, and will produce the three lowest Dates and Meetings Value for each Unique Value of P. If the number of Records for a given P are less than three, it will display them also, but no Records greater than three. First, a couple of assumptions:
  1. Table Name: tblTest
  2. Field Names/ Data Types:
    1. [P] {LONG}
    2. [Date] {DATE/TIME}
    3. [Meetings] {LONG}
    Expand|Select|Wrap|Line Numbers
    1. Dim strSQL1 As String
    2. Dim strSQL2 As String
    3. Dim MyDB As DAO.Database
    4. Dim rstUnique As DAO.Recordset          'Unique Values for P
    5. Dim rst As DAO.Recordset
    6. Dim intCtr As Integer
    7.  
    8. strSQL1 = "SELECT DISTINCT [P] FROM tblTest ORDER BY [P];"
    9.  
    10. Set MyDB = CurrentDb
    11. Set rstUnique = MyDB.OpenRecordset(strSQL1, dbOpenDynaset, dbOpenForwardOnly)
    12.  
    13. Debug.Print "---------------------------------------------"
    14. Debug.Print "P:", "Date:", "Meetings"
    15. Debug.Print "---------------------------------------------"
    16.  
    17. With rstUnique
    18.   Do While Not .EOF
    19.     strSQL2 = "SELECT * FROM tblTest WHERE [P] = " & ![P] & " ORDER BY [Date];"
    20.       Set rst = MyDB.OpenRecordset(strSQL2, dbOpenSnapshot)
    21.         Do While Not rst.EOF
    22.           intCtr = intCtr + 1
    23.             Debug.Print ![P], rst![Date], rst!Meetings
    24.               If intCtr = 3 Then Exit Do
    25.                 rst.MoveNext
    26.         Loop
    27.           intCtr = 0        'RESET
    28.           rst.MoveFirst
    29.       .MoveNext
    30.   Loop
    31. End With
    32.  
    33. rstUnique.Close
    34. rst.Close
    35. Set rstUnique = Nothing
    36. Set rst = Nothing
  3. OUTPUT based on Sample Data:
    Expand|Select|Wrap|Line Numbers
    1. ---------------------------------------------
    2. P:            Date:         Meetings
    3. ---------------------------------------------
    4.  1            12/1/2011      4 
    5.  1            12/2/2011      0 
    6.  1            12/3/2011      2 
    7.  2            12/1/2011      3 
    8.  2            12/2/2011      2 
    9.  2            12/7/2011      3 
    10.  3            12/3/2011      2 
    11.  3            12/4/2011      4 
    12.  3            12/5/2011      7 
    13.  4            1/23/2011      10 
    14.  4            9/16/2011      12 
    15.  5            5/30/2011      9 
P.S. - If you wish to take this approach, it will be a simple matter to write the Results to a Table for viewing, just let me know.
May 4 '11 #12

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: jochen scheire | last post by:
Is there a way I can calculate a field in a form based on another field in the same form. When clicking submit, both values should be posted to the next page. I want to be able to type in a value...
3
by: William Wisnieski | last post by:
Hello Again, I'm really stuck on this one.....so I'm going to try a different approach to this problem. I have a query by form that returns a record set in a datasheet. The user double...
1
by: john_liu | last post by:
I have a field called AMOUNT in MS Access with values of 10, 20, 30, 40, and I want to create another field called TOTAL like this: if the value in field AMOUNT=20, then TOTAL=AMOUNT*3, else...
1
by: compl | last post by:
I have a database that I need to restrict the ability to edit one field based on another. The two fields are DOS (date) and Amount (currency). I only want the users to be able to edit the Amount...
2
by: yesgirl | last post by:
Hello, In an Access 2003 form, I have a combo box that offers numerous selections. If certain values are chosen (i.e. "Done") then a date in another field in the form must be entered...
8
by: 14erclimb | last post by:
Hi, what a great resource this forum is! Hopefully you all can help: I have one field called "OPERATION_NO" another called "WORK_CENTER_NO" and another field called "OPER_STATUS_CODE" I'm using...
3
by: PowerLifter1450 | last post by:
Hi all, I have to Combo boxes on a form. The first one I would always like users to see. The second, however, I would like hidden if the first box has certain values selected. So, if ComboBox1 has...
1
by: gedwards | last post by:
I'm trying to create a database to keep track of donations. I have 2 tables. One that has all the person information plus the Amt. pledge, Amt. Paid, and Amt. Remaining. The other table had Date and...
2
by: MyWaterloo | last post by:
Ok. I have a form with a field for a sampler's name, number, and email address. The sampler's name is selected from a combo box that references a table with name, number, and email. I want to be...
11
by: clloyd | last post by:
I have a phone number field (BusinessPhone) that I only want to display in my query results if the user has selected yes (yes/no field) in another field (Business Y/N field). The premise is that...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.