Home > Enterprise >  SQL condition based on number on field name
SQL condition based on number on field name

Time:09-17

I have a table containing numbers of people in each area, by age. There is a column for each age, as shown in this table (junk data):

Area 0 1 2 3 ... 90
A 123 65 45 20 -- 66
B 442 456 124 422 -- 999
C 442 99 88 747 -- 234

I need to group these figures into age bands (0-19. 20-39, 40-59...) eg:

Area 0-19 20-39 40-59 60
A 789 689 544 1024
B 1564 884 1668 1589
C 800 456 456 951

What is the best way to do this?

I could do a simple SUM as below, but that feels like a massive amount of script for something that feels like it should be straightforward.

SELECT 
[0] [1] [2] ...[19] AS [0-19],
[20] [21] [22] ...[39] AS [20-39]
...

Is there a simpler way? I'm wondering if PIVOT can help but am struggling to visualise how to use it to get my desired result. Hoping I'm missing something obvious!


EDIT This is how the data has been supplied to me, I know it's not a great table design but unfortunately that's out of my hands.

CodePudding user response:

I would suggest creating a view on top of your table like so:

CREATE VIEW v_t_normal
SELECT Area, Age, Value
FROM t
CROSS APPLY (VALUES
    (0,  [0])
    (1,  [1])
    ...
    (90, [90 ])
) AS ca(Age, Value)

That view will normalize present your data in somewhat normalized form. You will not be able to edit the data in the view but you should be able to perform basic math and aggregation on the data. The 90 value will still cause headache as it encapsulates more than one value.

CodePudding user response:

I'm going to answer by suggesting an alternative table design which will make life easier:

Area | Age | Count
A    | 0   | 123
A    | 1   | 65
...
B    | 0   | 442

Here we are storing each area's age in a separate record, rather than column. With this design in place, your ask is easy to come by using conditional aggregation:

SELECT
    Area,
    SUM(CASE WHEN Age BETWEEN 0 AND 19  THEN Count ELSE 0 END) AS [0-19],
    SUM(CASE WHEN Age BETWEEN 20 AND 39 THEN Count ELSE 0 END) AS [20-39],
    ...
FROM yourNewTable
GROUP BY Area;
  • Related