0

I'm trying to create a stored procedure that will return 8 records, that should all be partitioned by a field to be unique, unless there are not enough unique values. It must return 8 records.

Sample data:

fld1 fld2 fld3
1 198 1480
2 200 1373
3 203 220
4 205 205
5 207 16678
6 212 205
7 214 220
8 221 16678
9 222 108
10 223 205

Currently, I have this for the stored procedure (missing a few lines) which works to return 8 records, as long as there are 8 unique values in fld3. The piece I'm stuck on is how to return 8 records in there are only 7 unique values in fld3 as in the data above. I would want 6 unique values in fld 3 and then 2 records that would have the same values in fld 3 but also not one of the previously chosen 6 records. Any suggestions?

CREATE PROCEDURE usp_Get8Records
  --passing in variables here
AS
BEGIN TRY
  SET NOCOUNT ON;
  SET XACT_ABORT ON;
  SELECT TOP 8 fld1, fld2, fld3
  FROM (
    SELECT DISTINCT fld1,
                    fld2,
                    fld3,
                    row_number() OVER (partition by fld3 order by fld1) AS rn
    FROM tblName
    GROUP BY fld1, fld2, fld3
        ) t WHERE rn <= 1'
END TRY
BEGIN CATCH
  --error hander
END CATCH
7
  • Why are you using dynamic SQL? Commented Sep 7, 2022 at 22:16
  • And if there are only 7 unique values, what are the 8 rows you are expecting? Please show your desired results. Commented Sep 7, 2022 at 22:17
  • the full sp is actually building some filtering in that i didn't show in the question so i'm building it with dynamic sql. As far as the question of returning 8 rows when there are 7 unique values is that it's a requirement. Our lab staff wants to select 8 samples every so of from new specimens that have been tested in a time period. Generally, there will always be more than 8 unique values in fld3, but that may not always be the case and they have to test 8. Commented Sep 7, 2022 at 22:21
  • 1
    1) Given you have managed to simplify the scenario - well done - why not just show us the static SQL? Easier for all. 2) You still have to define to us what the 8th row should look like - else how would we know to write a query? Commented Sep 7, 2022 at 22:23
  • 1
    Then it should get 8 unique values Commented Sep 7, 2022 at 23:38

2 Answers 2

0

Use the row_number() function to order your rows a bit like your were doing, but combine with TOP 8.

You can modify the row number ordering to meet any other requirements you might have.

declare @MyTable table (fld1 int, fld2 int, fld3 int);

insert into @MyTable (fld1, fld2 ,fld3)
values
(1, 198, 1480),
(2, 200, 1373),
(3, 203, 220),
(4, 205, 205),
(5, 207, 16678),
(6, 212, 205),
(7, 214, 220),
(8, 221, 16678),
(9, 222, 108),
(10, 223, 205);

select top 8 *
from @MyTable
order by row_number() over (partition by fld3 order by fld2) asc;

Returns:

fld1 fld2 fld3
4 205 205
9 222 108
3 203 220
5 207 16678
1 198 1480
2 200 1373
6 212 205
7 214 220
Sign up to request clarification or add additional context in comments.

2 Comments

You can actually put ROW_NUMBER directly in the ORDER BY weirdly
@Charlieface true I keep forgetting that :)
0

You just need to order by fld1 and fld2 first before fld3, then take the top 8 rows.

I don't know whether you still need the GROUP BY, so I've left it in.

SELECT TOP (8)
  fld1,
  fld2,
  fld3
FROM tblName
GROUP BY
  fld1,
  fld2,
  fld3
ORDER BY
  fld1,
  fld2,
  fld3;

2 Comments

For some reason that doesn't return all the unique values first i.e. when I ran it I didn't get fld3=108.
Might have misunderstood the question, it was a little unclear

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.