2

I have the following table:

MyTable
PlaceID NameID  Code    CodeCount
1       1       1234A   2
1       2       1234A   3
1       3       1234A   1
2...
2...
3...
3...

I want to select 1234A where PlaceID = 1, the number of times equal to the sum of the CodeCount. So, the result would be six rows like this:

MyResult
Code    
1234A
1234A
1234A
1234A
1234A
1234A

Eventually, this selection will have a bunch of different codes for a single PlaceID. YES I know I'm duplicating data, in the end it's not going to be a lot and I'll explain why I'm doing this below.

First, I needed to get the sum of the counts:

DECLARE @cdcnt INT = (SELECT SUM(CodeCount) FROM MyTable WHERE PlaceID = 1 AND Code = '1234A')

Then I can use this value as a control in a while loop to select the value that many times:

DECLARE @i INT = 0;
WHILE @i < @cdcnt
BEGIN
    SELECT DISTINCT Code
    FROM MyTable
    WHERE PlaceID = 1 AND Code = '1234A'
    SET @i = @i + 1
END

The problem is I get 6 separate selections, instead of one selection with 6 rows. How do I create MyResult shown above, instead of 6 separate selections?

Why I am doing this: I want to use a random number generator to pick a Code with the frequency at which it appears in aggregate for each PlaceID (there will be other Codes added, I'm still figuring out how to do just one). I am open to suggestions for different ways of doing this, but it's the only way I could figure out how. If there's a function already built to pick from a list according to a set frequencies, I'm all ears.

0

1 Answer 1

2

Below is an example using a join to a tally CTE. It would be better to create a materialized tally/numbers table to facilitate this sort of task going forward and improve performance too.

WITH
     t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
    ,tally AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
    ,codes AS (SELECT Code, SUM(CodeCount) AS CodeCount FROM dbo.MyTable WHERE Code = '1234A' AND PlaceID = 1 GROUP BY Code)
SELECT Code
FROM codes
JOIN tally ON tally.num <= codes.CodeCount;
4
  • I have to look at these things a little longer to understand them....
    – Dan
    Commented Apr 18, 2020 at 18:29
  • Just in case this doesn't get deleted Ill mark this as the answer. It looks like with anything prior to SQL 2016, I need to build an auxillary/materialized tally/numbers table. With 2016, theres a way to do it just from the counts! Thanks!
    – Dan
    Commented Apr 23, 2020 at 11:47
  • @Dan, CTEs have been around for a while, SQL 2005 IIRC. But a numbers table will generally provide better performance.
    – Dan Guzman
    Commented Apr 23, 2020 at 11:55
  • Thanks! I did with Excel and XML a couple years ago and now need a SQL Server solution. This, and the linked questions help a ton!
    – Dan
    Commented Apr 23, 2020 at 12:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.