0

I have a table with column "Age", where sorted age is shown like:

10 years,
105 years
18 years,
60 years.
8 months.

How can I sort it not in alphabetical order, but in correct. I can't eliminate word "years".

Alex Blokha
  • 1,141
  • 2
  • 17
  • 30

2 Answers2

0

Well, if this is from say a database?

Then you could do this:

SELECT id, FirstName, LastName, Age, 
  cast(SUBSTRING(Age,1,Charindex(' ',Age)-1 ) as integer) as NumAge
  FROM tblCustomers
  ORDER BY NumAge

So, now you have a text display column, but you also have a real "number" column with the actual number in years - and you can sort correctly on that NumAge column. And this sort could also be done with a data-view sort - so however you were/are sorting the data, then sorting by NumAge will become a possible choice if you add the above column that plucks out the number from that column.

Now the Above works if we don't have a mix of month, and years. But, to handle that, then we change above to this:

SELECT id, FirstName, LastName, Age, 
    CASE
      WHEN CharIndex('month',Age) > 0 THEN
        (cast(SUBSTRING(Age,1,Charindex(' ',Age)-1 ) as integer))
      WHEN CharIndex('year',Age) > 0 THEN
        (cast(SUBSTRING(Age,1,Charindex(' ',Age)-1 ) * 12 as integer))
    END 
     AS AgeInMonths
  FROM tblCustomers
  ORDER BY AgeInMonths

So, once again, we now have a number and value in months for age, and this can be sorted. So we display the Age + text column, but the sort expression can use AgeInMonths and the result is data in the correct order.

And if you have days? Then I would in place of the months * 12, using months * 30, and for year, then just use * 365. So, it not at all hard to have support for years, months, or days.

The result is once again, data sorted in number order by given age.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • How can I show 15 years, but store ans sort like "15"? – Alex Blokha Apr 02 '21 at 14:48
  • Quite much thought I just explained how. You simply continue to display your text column, but when you sort, you sort on the new column. So you now have two columns - your existing one for display with age + text, but you now simply sort based on this now available number column. So your sort or order by expression will work against NumAge. However, the months example column is a issue - I'll update my post to handle that issue. – Albert D. Kallal Apr 02 '21 at 16:35
  • See my edit to the above post - I added support for years, and months. – Albert D. Kallal Apr 02 '21 at 16:56
0

The problem is also "months". Is 8 months higher than 2 years or is 8 months 0 year? If it is the last you can use Linq. Lets say this are the ages.

var age = new List<string>()
{
    "10 years,",
    "105 years",
    "18 years,",
    "60 years.",
    "8 months.",
    "1 year.",
    "18 months,",
 };

Then you can do this. It splits the list in months and years. Then removes all characters except numbers. If it is a month divide it by 12 to get the years. Then sort it, and make it a string again and add "years" to it.

var sortedAge = age.Where(x => x.ToLower().Contains("month"))
   .Select(x => Convert.ToInt32(string.Concat(x.Where(Char.IsDigit))) / 12)
   .Concat(age.Where(x => x.ToLower().Contains("year"))
   .Select(x => Convert.ToInt32(string.Concat(x.Where(Char.IsDigit)))))
   .OrderBy(y => y)
   .Select(z => z > 1 ? z.ToString() + " years" : z.ToString() + " year").ToList();

result

0 year
1 year
1 year
10 years
18 years
60 years
105 years

But you would still be better off just storing the age as an int in the DOB or even better, the date of birth as datetime.

VDWWD
  • 35,079
  • 22
  • 62
  • 79
  • so, if I store birthdate, how can I show age and sort by it? – Alex Blokha Apr 02 '21 at 14:19
  • If you store brthdate you can simply calculate the age: https://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-based-on-a-datetime-type-birthday – VDWWD Apr 02 '21 at 14:30
  • It is a heck of a lot easier to scale up the numbers then trying to divide them down. Just assume everything is in months - and the whole problem becomes easy. One will continue to display the age + text, but you simply sort on a column that represents the months. (see my post above). However, it not at all clear why the DOB, or some number value was never stored/saved in the first place. But, see my post - I show a rather easy T-SQL means of converting the given text into a number of months value , and then one can sort on that AgeInMonths, but continue to display the age + text. – Albert D. Kallal Apr 02 '21 at 17:05
  • If you have the option to save DOB, then it will automatic always sort by number value. You use a date, or datetime column for this. This allows you to display the DOB format anyway you want, including things like You are 2 years, 5 months and 3 days old. So without question go with a date/datetime column, since how you display that column does not effect that sorting by DOB - it will always automatic and always sort by correct order. and you can use Month(DOB) to get the current month, so a query to show who has a birthday this month is also trivial. – Albert D. Kallal Apr 02 '21 at 17:20