This puzzle takes us into Discrete Mathematics and Number Theory, where numbers aren’t just values—they’re types. Whether a number is odd, even, prime, or part of a sequence like Fibonacci, Number Theory is all about how we classify them. I started by generating a table of integers and labeling each with its corresponding classification. A simple idea, but it quickly expanded—turns out the number of number types is bigger than I thought. Let’s see what we can uncover.
I’ve provided a brief overview of each classification, along with the relevant SQL, below. However, I encourage you to explore this topic further through your own research to deepen your understanding of it. With that in mind, let’s dive into how we can categorize these classifications.
❗The full Microsoft T-SQL used to create this analysis is located at the end of this post.
Here are the classifications we’ll be working with….
Basic Properties
- Odd / Even
- Negative / Positive
- Integer / Decimal
- Whole
- Natural
- Real
Number Theory
- Prime
- Composite
- Perfect
- Abundant
- Deficient
Special Forms
- Square
- Triangular
- Cube
- Factorial
Sequences
- Fibonacci
Patterns
- Palindromic
- Harshad (Niven)
- Armstrong (Narcissistic)
Classifications Beyond SQL
Some categories don’t map well to SQL because they involve infinite precision or complex numbers:
- Irrational numbers (π, √2, e)
- Rational numbers (fractions in reduced form)
- Imaginary numbers (involving i = √-1)
Others are possible but too elaborate for this blog post, such as:
- Happy / Sad Numbers
- Amicable / Sociable Numbers
- Highly Composite Numbers
- Catalan Numbers
Classifying Numbers
Now, let’s dive into how to calculate each classification using SQL.
Creating the Numbers Table
For this analysis, we will use the GENERATE_SERIES to generate a Numbers table for the integers -100 through +100.
SELECT value AS Number
INTO ##Numbers
FROM GENERATE_SERIES(-100, 100);
GOEven / Odd
Classifying a number as even or odd is one of the simplest number properties.
- A number is even if it can be divided by 2 with no remainder.
- A number is odd if it has a remainder of 1 when divided by 2.
Another way to describe even numbers is with the formula 2n. Any integer n multiplied by 2 will always produce an even number. Similarly, numbers of the form 2n + 1 will always be odd.
In SQL, we can use the modulo operator (%) to check for evenness.
-- Even and Odd Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT Number,
CASE WHEN Number % 2 = 0 THEN 'Even' ELSE 'Odd' END AS NumberType
INTO ##Odd_Even
FROM cte_Numbers
ORDER BY 1;
GONegative / Positive
Numbers can also be classified based on their sign:
- Negative numbers are less than zero.
- Positive numbers are greater than zero.
- Zero itself is neither positive nor negative, so it is excluded from both categories.
In SQL, we can use a simple CASE expression to classify numbers by comparing them directly to zero.
-- Negative and Positive Numbers
SELECT Number,
CASE WHEN Number < 0 THEN 'Negative' WHEN Number > 0 THEN 'Positive' END AS NumberType
INTO ##Negative_Positive
FROM ##Numbers
ORDER BY 1;
GOIntegers / Decimals
Another fundamental way to classify numbers is whether they are integers (whole numbers) or decimals (numbers with a fractional part).
- An integer is any number without a fractional component.
- A decimal is any number that has digits after the decimal point.
In mathematics, all integers are real numbers, but not all real numbers are integers.
There are two methods in SQL to determine if a number is an integer or a decimal. We will cover them both here.
The first method is to use the FLOOR function.
-- Integers and Decimal Numbers
SELECT Number,
CASE WHEN Number = FLOOR(Number) THEN 'Integer' ELSE 'Decimal' END AS NumberType
INTO ##Integer_Decimal
FROM ##Numbers;
GOThe second method is to divide by one and determine if a remainder is present.
SELECT Number,
CASE WHEN CAST(Number AS DECIMAL(18,10)) % 1 = 0 THEN 'Integer' ELSE 'Decimal' END AS NumberType
--INTO ##Integer_Decimal
FROM ##Numbers;
GOWhole Numbers
Whole numbers are the set of non-negative integers: 0, 1, 2, 3, 4, …
They include zero and all positive counting numbers, but exclude negative numbers and decimals.
-- Whole Numbers
SELECT Number,
'Whole' AS NumberType
INTO ##Whole
FROM ##Numbers
WHERE Number = FLOOR(Number) AND
Number >= 0;
GOReal Numbers
The real numbers are essentially all the numbers you can plot on a number line. They include:
- Negative numbers (-3, -2.5, -1)
- Zero (0)
- Positive numbers (2, 3.14, 100)
- Integers and decimals
- Rational numbers (fractions that can be expressed as decimals)
- Irrational numbers (π or the square root of 2).
In mathematics, the only things excluded from the real numbers are imaginary numbers.
Since everything we can store in SQL Server (integers, floats, decimals) falls into the category of real numbers, the classification is straightforward: every number in our dataset is real.
-- Real Numbers
SELECT Number,
'Real' AS NumberType
INTO ##Real
FROM ##Numbers;
GOPrime Numbers
A prime number is a natural number greater than 1 that has no divisors other than 1 and itself.
Examples:
- Primes → 2, 3, 5, 7, 11, 13, 17
- Not Primes → 1 (not prime by definition), 4 (divisible by 2), 9 (divisible by 3), 15 (divisible by 3 and 5)
This makes primes the building blocks of integers, since every number can be uniquely factored into primes (the Fundamental Theorem of Arithmetic).
Here, we will use recursion to determine prime numbers.
-- Prime Numbers
WITH cte_PrimeCheck AS
(
SELECT n.Number,
3 AS Divisor,
CASE WHEN n.Number > 0 THEN Number ELSE 0 END AS Max_Divisor
FROM ##Numbers n
WHERE n.Number > 2 AND
n.Number % 2 != 0
UNION ALL
SELECT Number,
Divisor + 2,
Max_Divisor
FROM cte_PrimeCheck
WHERE Divisor <= Max_Divisor AND
Number % Divisor != 0
)
SELECT n.Number,
CASE
WHEN n.Number <= 1 THEN NULL -- exclude 0 and 1
WHEN n.Number = 2 THEN 'Prime' -- special case for 2
WHEN n.Number % 2 = 0 THEN NULL -- eliminate even numbers > 2
WHEN EXISTS (
SELECT 1
FROM cte_PrimeCheck p
WHERE p.number = n.Number AND
n.Number % p.divisor = 0
) THEN 'Not Prime' -- found a divisor
ELSE 'Prime' -- otherwise prime
END AS NumberType
INTO ##Prime
FROM cte_PrimeCheck n
OPTION (MAXRECURSION 0);
GOComposite Numbers
A composite number is a positive integer greater than 1 that has at least one proper divisor other than 1 and itself. In other words, it’s not prime.
- Composite: 4 (2×2), 6 (2×3), 8 (2×4), 9 (3×3), 10 (2×5)
- Not Composite: 1 (neither prime nor composite), 2 (prime), 3 (prime), 5 (prime)
You can determine composites by checking whether a number has any divisor between 2 and n−1.
-- Composite Numbers (Opposite of Prime Numbers)
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT
Number,
'Composite' AS NumberType
INTO ##Composite
FROM cte_Numbers n
WHERE n.Number > 1
AND EXISTS (
SELECT 1
FROM cte_Numbers d
WHERE d.Number > 1
AND d.Number < n.Number
AND n.Number % d.Number = 0
);
GOPerfect Squares
A perfect square is an integer that can be expressed as the square of another integer.
Examples:
- Perfect Squares: 0 (0²), 1 (1²), 4 (2²), 9 (3²), 16 (4²), 25 (5²)
- Not Perfect Squares: 2, 3, 5, 6, 7, 8
-- Perfect Squares
SELECT Number,
'Square' AS NumberType
INTO ##Square
FROM ##Numbers
WHERE SQRT(Number) = FLOOR(SQRT(Number)) AND
Number >= 0;
GOPerfect Cubes
A perfect cube is an integer that can be expressed as another integer raised to the third power.
Examples:
- Perfect Cubes: −8(-2^3), −1(1^3), 0(0^3), 1 (1^3), 8 (2^3), 27 (3^3), 64 (4^3)
- Not Perfect Cubes: 2, 3, 5, 6, 7, 9
Unlike squares, cubes can be negative since the cube of a negative integer is also negative.
-- Perfect Cubes
WITH cte_Cube AS
(
SELECT Number,
POWER(Number,3.0) AS Cube
FROM ##Numbers
)
SELECT Cube AS Number,
'Cube' AS NumberType
INTO ##Cube
FROM cte_Cube
WHERE Cube IN (SELECT Number FROM ##Numbers)
ORDER BY 1;
GOFibonacci Numbers
The Fibonacci sequence is one of the most famous mathematical sequences. Each number in the sequence is the sum of the two numbers before it.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…
Fibonacci numbers appear in many natural patterns—spirals in shells, branching in trees, and even the arrangement of sunflower seeds.
-- Fibonacci Numbers
WITH cte_Recursion (PrevNumber, Number) AS
(
SELECT 0, 1
UNION ALL
SELECT Number,
PrevNumber + Number
FROM cte_Recursion
WHERE Number < 100
)
SELECT DISTINCT PrevNumber AS Number,
'Fibonacci' AS NumberType
INTO ##Fibonacci
FROM cte_Recursion
OPTION (MAXRECURSION 0);
GOTriangular Numbers
A triangular number is a number that can form an equilateral triangular dot pattern.
Examples:
- Triangular: 1, 3, 6, 10, 15, 21, 28, …
- Not Triangular: 2, 4, 5, 7, 8, 9
For instance, 6 is triangular because: 6 = 1+2+3
Visually, you could arrange six dots into a perfect triangle.
We can use the formula n(n+1)/2 to generate triangular numbers and check if a candidate number matches:
-- Triangular Numbers
SELECT Number,
'Triangular' AS NumberType
INTO ##Triangular
FROM ##Numbers
WHERE Number > 0
AND EXISTS (
SELECT 1
FROM ##Numbers n
WHERE n.Number > 0
AND n.Number * (n.Number + 1) / 2 = ##Numbers.Number
);
GOPalindromic Numbers
A palindromic number is a number that reads the same forwards and backwards, much like the word racecar.
Examples:
- Palindromic: 0, 1, 22, 121, 1331, 12321
- Not Palindromic: 12, 123, 4567
By convention, we normally exclude negative numbers, since the minus sign (-) breaks the symmetry. For example, -121 reversed becomes 121-, which is not the same.
-- Palindromic Numbers
SELECT Number,
'Palindromic' AS NumberType
INTO ##Palindromic
FROM ##Numbers
WHERE CAST(Number AS VARCHAR(20)) = REVERSE(CAST(Number AS VARCHAR(20))) AND
Number >= 0;
GOAbundant Numbers
An abundant number is a positive integer whose sum of proper divisors (all positive divisors less than the number itself) is greater than the number.
Examples:
- Abundant: 12 (divisors: 1, 2, 3, 4, 6 → sum = 16 > 12), 18 (1, 2, 3, 6, 9 → 21 > 18), 20 (1, 2, 4, 5, 10 → 22 > 20)
- Not Abundant: 6 (perfect), 8 (deficient), 28 (perfect)
Abundant numbers sit alongside deficient (sum < n) and perfect (sum = n) numbers; together they partition the positive integers >1.
--Abundant Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Abundant' AS NumberType
INTO ##Abundant
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) > n.Number;
GODeficient Numbers
A deficient number is a positive integer whose sum of proper divisors (all positive divisors less than the number itself) is less than the number.
Examples:
- Deficient: 8 (divisors: 1, 2, 4 → sum = 7<8), 10 (1, 2, 5 → 8<10), 14 (1, 2, 7 → 10<14)
- Not Deficient: 6 (perfect), 12 (abundant), 28 (perfect)
Deficient, perfect, and abundant numbers form a clean trio that partitions the integers greater than 1.
-- Deficient Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Deficient' AS NumberType
INTO ##Deficient
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) < n.Number;
GOPerfect Numbers
A perfect number is a positive integer that equals the sum of its proper divisors (all positive divisors less than the number itself).
Classic examples:
- 6 → divisors: 1, 2, 3 → 1+2+3 = 6
- Next few: 496, 8128 (they get rare quickly!)
- 28 → divisors: 1, 2, 4, 7, 14 → 1+2+4+7+14 = 28
Convention note: 1 is not perfect (its proper-divisor sum is 0).
-- Perfect Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Perfect' AS NumberType
INTO ##Perfect
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) = n.Number;
GOHarshad (Niven) Numbers
A Harshad (or Niven) number is a positive integer that is divisible by the sum of its digits.
Examples:
- 18 → digits 1+8 = 9; 18 mod 9 = 0 → Harshad
- 21 → digits 2+1 = 3; 21 mod 3 = 0 → Harshad
- 19 → digits 1+9 = 10; 19 mod 10 = 9 → not Harshad
-- Harshad (Niven) Numbers
WITH cte_Digits AS
(
SELECT n.Number,
CAST(SUBSTRING(s.Digits, v.n, 1) AS INT) AS Digit
FROM ##Numbers n
CROSS APPLY (SELECT CAST(ABS(n.Number) AS VARCHAR(20)) AS Digits) s
CROSS APPLY (SELECT TOP (LEN(s.Digits)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.objects) v
),
cte_DigitSums AS
(
SELECT Number,
SUM(Digit) AS DigitSum
FROM cte_Digits
GROUP BY Number
)
SELECT ds.Number,
'Harshad (Niven)' AS NumberType
INTO ##Harshad
FROM cte_DigitSums ds
WHERE ds.Number > 0 AND
ds.Number % ds.DigitSum = 0
ORDER BY ds.Number;
GOArmstrong (Narcissistic) Numbers
An Armstrong (or narcissistic) number is an integer that is equal to the sum of its digits, each raised to the power of the number of digits.
Examples:
- 153 → 1^3 + 5^3 + 3^3 = 153 → Armstrong
- 370 → 3^3 + 7^3 + 0^3 = 370 → Armstrong
- 9474 → 9^4+4^4+7^4+4^4 = 9474 → Armstrong
- 123 → 1^3+2^3+3^3 = 36 ≠ 123 → not Armstrong
Typically, we consider non-negative integers for this classification.
-- Armstrong (Narcissistic) Numbers
WITH cte_Digits AS
(
SELECT n.Number,
LEN(CAST(ABS(n.Number) AS VARCHAR(20))) AS NumDigits,
CAST(SUBSTRING(s.Digits, v.n, 1) AS INT) AS Digit,
s.Digits,
v.n
FROM ##Numbers n CROSS APPLY
(SELECT CAST(ABS(n.Number) AS VARCHAR(20)) AS Digits) s CROSS APPLY
(SELECT TOP (LEN(s.Digits)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.objects) v
),
cte_DigitPowers AS
(
SELECT Number,
SUM(POWER(Digit, NumDigits)) AS DigitPowerSum
FROM cte_Digits
GROUP BY Number
)
SELECT dp.Number,
'Armstrong (Narcissistic)' AS NumberType
INTO ##Armstrong
FROM cte_DigitPowers dp
WHERE dp.Number = dp.DigitPowerSum AND
dp.Number >= 0
ORDER BY dp.Number;
GOFactorial Numbers
A factorial number is any number that equals n! for some non-negative integer n.
Examples:
- 0! = 1
- 1! = 1
- 2! = 2
- 3! = 6
- 4! = 24
- 5! = 120 ….
-- Factorial Numbers
WITH cte_Bound AS
(
SELECT CAST(ABS(MAX(CAST(Number AS BIGINT))) AS BIGINT) AS MaxAbs
FROM ##Numbers
),
cte_Factorials AS
(
SELECT 0 AS n,
CAST(1 AS DECIMAL(38,0)) AS Fact
FROM cte_Bound
UNION ALL
SELECT n + 1,
CAST(Fact * (n + 1) AS DECIMAL(38,0))
FROM cte_Factorials CROSS JOIN
cte_Bound
WHERE CAST(Fact * (n + 1) AS DECIMAL(38,0)) <= MaxAbs
)
SELECT DISTINCT
CAST(f.Fact AS BIGINT) AS Number,
'Factorial' AS NumberType
INTO ##Factorial
FROM cte_Factorials f INNER JOIN
(
SELECT DISTINCT CAST(Number AS DECIMAL(38,0)) AS NumberInt
FROM ##Numbers
WHERE Number >= 0 AND Number = FLOOR(Number)
) n
ON n.NumberInt = f.Fact
ORDER BY Number
OPTION (MAXRECURSION 32767);
GOSummary by Group
Now that each number has been individually classified, we can also group them together by their classification profile. This allows us to identify which numbers share the same combination of properties.
For example:
- All negative even integers collapse into a single group.
- All abundant even numbers under 100 are grouped together.
- Certain “special” numbers (like 0, 1, 28, etc.) remain in groups of their own.
Count = 1 (29 groups)
- Number: 0
Classifications: Even, Integer, Whole Number, Real, Square, Cube, Fibonacci, Palindromic - Number: 1
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Square, Cube, Fibonacci, Triangular, Palindromic - Number: 2
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Prime, Fibonacci, Palindromic, Deficient - Number: 3
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Fibonacci, Triangular, Palindromic, Deficient - Number: 4
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Square, Palindromic, Deficient - Number: 5
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Prime, Fibonacci, Palindromic, Deficient - Number: 6
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Triangular, Palindromic, Perfect - Number: 7
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Prime, Palindromic, Deficient - Number: 8
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Cube, Fibonacci, Palindromic, Deficient - Number: 9
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Square, Palindromic, Deficient - Number: 10
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Triangular, Deficient - Number: 11
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Prime, Palindromic, Deficient - Number: 16
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Square, Deficient - Number: 21
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Fibonacci, Triangular, Deficient - Number: 24
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Abundant - Number: 27
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Cube, Deficient - Number: 28
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Triangular, Perfect - Number: 34
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Fibonacci, Deficient - Number: 36
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Square, Triangular, Abundant - Number: 45
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Triangular, Deficient - Number: 50
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Deficient - Number: 55
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Fibonacci, Triangular, Palindromic, Deficient - Number: 63
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Deficient - Number: 64
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Square, Cube, Deficient - Number: 66
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Triangular, Palindromic, Abundant - Number: 78
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Triangular, Abundant - Number: 81
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Square, Deficient - Number: 88
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Palindromic, Abundant - Number: 100
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Square, Abundant
Count = 2 (7 groups)
- Numbers: -1, -27
Classifications: Odd, Negative, Integer, Real, Cube - Numbers: -8, -64
Classifications: Even, Negative, Integer, Real, Cube - Numbers: 44, 22
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Palindromic, Deficient - Numbers: 49, 25
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Square, Deficient - Numbers: 89, 13
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Prime, Fibonacci, Deficient - Numbers: 91, 15
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Triangular, Deficient - Numbers: 96, 56
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Abundant
Count = 3 (1 group)
- Numbers: 99, 77, 33
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Palindromic, Deficient
Count = 11 (1 group)
- Numbers: 95, 93, 87, 85, 75, 69, 65, 57, 51, 39, 35
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Not Prime, Composite, Deficient
Count = 14 (1 group)
- Numbers: 90, 84, 80, 72, 70, 60, 54, 48, 42, 40, 30, 20, 18, 12
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Abundant
Count = 16 (1 group)
- Numbers: 98, 94, 92, 86, 82, 76, 74, 68, 62, 58, 52, 46, 38, 32, 26, 14
Classifications: Even, Positive, Integer, Whole Number, Natural Number, Real, Composite, Deficient
Count = 18 (1 group)
- Numbers: 97, 83, 79, 73, 71, 67, 61, 59, 53, 47, 43, 41, 37, 31, 29, 23, 19, 17
Classifications: Odd, Positive, Integer, Whole Number, Natural Number, Real, Prime, Deficient
Count = 48 (2 groups)
- Numbers: -2,-4,-6,-10,-12,-14,-16,-18,-20,-22,-24,-26,-28,-30,-32,-34,-36,-38,-40,-42,-44,-46,-48,-50,-52,-54,-56,-58,-60,-62,-66,-68,-70,-72,-74,-76,-78,-80,-82,-84,-86,-88,-90,-92,-94,-96,-98,-100
Classifications: Even, Negative, Integer, Real - Numbers: -3,-5,-7,-9,-11,-13,-15,-17,-19,-21,-23,-25,-29,-31,-33,-35,-37,-39,-41,-43,-45,-47,-49,-51,-53,-55,-57,-59,-61,-63,-65,-67,-69,-71,-73,-75,-77,-79,-81,-83,-85,-87,-89,-91,-93,-95,-97,-99
Classifications: Odd, Negative, Integer, Real
To create a table of the above classifications, you can use the following SQL.
-- Results
SELECT
STRING_AGG(CONVERT(varchar(50), n.Number), ',') WITHIN GROUP (ORDER BY n.Number DESC) AS numbers,
COUNT(*) AS count,
oe.NumberType AS Even_Odd,
np.NumberType AS Negative_Positive,
id.NumberType AS Integer_Decimal,
w.NumberType AS Whole,
nat.NumberType AS Natural,
r.NumberType AS Real,
p.NumberType AS Prime,
c.NumberType AS Composite,
sq.NumberType AS Square,
cu.NumberType AS Cube,
fib.NumberType AS Fibonacci,
tri.NumberType AS Triangular,
pal.NumberType AS Palindromic,
ab.NumberType AS Abundant,
de.NumberType AS Deficient,
pe.NumberType AS Perfect,
h.NumberType AS Harshad,
a.NumberType AS Armstrong,
f.NumberType AS Factorial
INTO ##Result
FROM ##Numbers n
LEFT JOIN ##Odd_Even oe ON n.Number = oe.Number
LEFT JOIN ##Negative_Positive np ON n.Number = np.Number
LEFT JOIN ##Integer_Decimal id ON n.Number = id.Number
LEFT JOIN ##Whole w ON n.Number = w.Number
LEFT JOIN ##Natural nat ON n.Number = nat.Number
LEFT JOIN ##Real r ON n.Number = r.Number
LEFT JOIN ##Prime p ON n.Number = p.Number
LEFT JOIN ##Composite c ON n.Number = c.Number
LEFT JOIN ##Square sq ON n.Number = sq.Number
LEFT JOIN ##Cube cu ON n.Number = cu.Number
LEFT JOIN ##Fibonacci fib ON n.Number = fib.Number
LEFT JOIN ##Triangular tri ON n.Number = tri.Number
LEFT JOIN ##Palindromic pal ON n.Number = pal.Number
LEFT JOIN ##Abundant ab ON n.Number = ab.Number
LEFT JOIN ##Deficient de ON n.Number = de.Number
LEFT JOIN ##Perfect pe ON n.Number = pe.Number
LEFT JOIN ##Harshad h ON n.Number = h.Number
LEFT JOIN ##Armstrong a ON n.Number = a.Number
LEFT JOIN ##Factorial f ON n.Number = f.Number
GROUP BY
oe.NumberType,
np.NumberType,
id.NumberType,
w.NumberType,
nat.NumberType,
r.NumberType,
p.NumberType,
c.NumberType,
sq.NumberType,
cu.NumberType,
fib.NumberType,
tri.NumberType,
pal.NumberType,
ab.NumberType,
de.NumberType,
pe.NumberType,
h.NumberType,
a.NumberType,
f.NumberType
ORDER BY 2,1;
GOIf you wish to execute the analysis in full. Here is the full SQL.
DROP TABLE IF EXISTS ##Numbers;
DROP TABLE IF EXISTS ##Odd_Even;
DROP TABLE IF EXISTS ##Negative_Positive;
DROP TABLE IF EXISTS ##Integer_Decimal;
DROP TABLE IF EXISTS ##Whole;
DROP TABLE IF EXISTS ##Natural;
DROP TABLE IF EXISTS ##Real;
DROP TABLE IF EXISTS ##Prime;
DROP TABLE IF EXISTS ##Composite;
DROP TABLE IF EXISTS ##Square;
DROP TABLE IF EXISTS ##Cube;
DROP TABLE IF EXISTS ##Fibonacci;
DROP TABLE IF EXISTS ##Triangular;
DROP TABLE IF EXISTS ##Palindromic;
DROP TABLE IF EXISTS ##Abundant;
DROP TABLE IF EXISTS ##Deficient;
DROP TABLE IF EXISTS ##Perfect;
DROP TABLE IF EXISTS ##Harshad
DROP TABLE IF EXISTS ##Armstrong
DROP TABLE IF EXISTS ##Factorial
DROP TABLE IF EXISTS ##Result;
GO
SET NOCOUNT ON;
GO
DROP TABLE IF EXISTS ##Numbers;
GO
SELECT value AS Number
INTO ##Numbers
FROM GENERATE_SERIES(-100, 100);
GO
--------------------------------------------
--------------------------------------------
-- Even and Odd Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT Number,
CASE WHEN Number % 2 = 0 THEN 'Even' ELSE 'Odd' END AS NumberType
INTO ##Odd_Even
FROM cte_Numbers
ORDER BY 1;
GO
--------------------------------------------
--------------------------------------------
-- Negative and Positive Numbers
SELECT Number,
CASE WHEN Number < 0 THEN 'Negative' WHEN Number > 0 THEN 'Positive' END AS NumberType
INTO ##Negative_Positive
FROM ##Numbers
ORDER BY 1;
GO
--------------------------------------------
--------------------------------------------
-- Integers and Decimal Numbers
SELECT Number,
CASE WHEN Number = FLOOR(Number) THEN 'Integer' ELSE 'Decimal' END AS NumberType
INTO ##Integer_Decimal
FROM ##Numbers;
GO
SELECT Number,
CASE WHEN CAST(Number AS DECIMAL(18,10)) % 1 = 0 THEN 'Integer' ELSE 'Decimal' END AS NumberType
--INTO ##Integer_Decimal
FROM ##Numbers;
GO
--------------------------------------------
--------------------------------------------
-- Whole Numbers
SELECT Number,
'Whole' AS NumberType
INTO ##Whole
FROM ##Numbers
WHERE Number = FLOOR(Number) AND
Number >= 0;
GO
--------------------------------------------
--------------------------------------------
-- Real Numbers
SELECT Number,
'Real' AS NumberType
INTO ##Real
FROM ##Numbers;
GO
--------------------------------------------
--------------------------------------------
-- Prime Numbers
WITH cte_PrimeCheck AS
(
SELECT n.Number,
3 AS Divisor,
CASE WHEN n.Number > 0 THEN Number ELSE 0 END AS Max_Divisor
FROM ##Numbers n
WHERE n.Number > 2 AND
n.Number % 2 != 0
UNION ALL
SELECT Number,
Divisor + 2,
Max_Divisor
FROM cte_PrimeCheck
WHERE Divisor <= Max_Divisor AND
Number % Divisor != 0
)
SELECT n.Number,
CASE
WHEN n.Number <= 1 THEN NULL -- exclude 0 and 1
WHEN n.Number = 2 THEN 'Prime' -- special case for 2
WHEN n.Number % 2 = 0 THEN NULL -- eliminate even numbers > 2
WHEN EXISTS (
SELECT 1
FROM cte_PrimeCheck p
WHERE p.number = n.Number AND
n.Number % p.divisor = 0
) THEN 'Not Prime' -- found a divisor
ELSE 'Prime' -- otherwise prime
END AS NumberType
INTO ##Prime
FROM cte_PrimeCheck n
OPTION (MAXRECURSION 0);
GO
--------------------------------------------
--------------------------------------------
-- Natural Numbers (also called Counting Numbers)
SELECT Number,
'Natural' AS NumberType
INTO ##Natural
FROM ##Numbers
WHERE Number = FLOOR(Number) AND
Number >= 1;
GO
--------------------------------------------
--------------------------------------------
-- Composite Numbers (Opposite of Prime Numbers)
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT
Number,
'Composite' AS NumberType
INTO ##Composite
FROM cte_Numbers n
WHERE n.Number > 1
AND EXISTS (
SELECT 1
FROM cte_Numbers d
WHERE d.Number > 1
AND d.Number < n.Number
AND n.Number % d.Number = 0
);
GO
--------------------------------------------
--------------------------------------------
-- Perfect Squares
SELECT Number,
'Square' AS NumberType
INTO ##Square
FROM ##Numbers
WHERE SQRT(Number) = FLOOR(SQRT(Number)) AND
Number >= 0;
GO
--------------------------------------------
--------------------------------------------
-- Perfect Cubes
WITH cte_Cube AS
(
SELECT Number,
POWER(Number,3.0) AS Cube
FROM ##Numbers
)
SELECT Cube AS Number,
'Cube' AS NumberType
INTO ##Cube
FROM cte_Cube
WHERE Cube IN (SELECT Number FROM ##Numbers)
ORDER BY 1;
GO
--------------------------------------------
--------------------------------------------
-- Fibonacci Numbers
WITH cte_Recursion (PrevNumber, Number) AS
(
SELECT 0, 1
UNION ALL
SELECT Number,
PrevNumber + Number
FROM cte_Recursion
WHERE Number < 100
)
SELECT DISTINCT PrevNumber AS Number,
'Fibonacci' AS NumberType
INTO ##Fibonacci
FROM cte_Recursion
OPTION (MAXRECURSION 0);
GO
--------------------------------------------
--------------------------------------------
-- Triangular Numbers
-- Find triangular numbers using formula: n(n+1)/2
SELECT Number,
'Triangular' AS NumberType
INTO ##Triangular
FROM ##Numbers
WHERE Number > 0
AND EXISTS (
SELECT 1
FROM ##Numbers n
WHERE n.Number > 0
AND n.Number * (n.Number + 1) / 2 = ##Numbers.Number
);
GO
--------------------------------------------
--------------------------------------------
-- Palindromic Numbers
SELECT Number,
'Palindromic' AS NumberType
INTO ##Palindromic
FROM ##Numbers
WHERE CAST(Number AS VARCHAR(20)) = REVERSE(CAST(Number AS VARCHAR(20))) AND
Number >= 0;
GO
--------------------------------------------
--------------------------------------------
--Abundant Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Abundant' AS NumberType
INTO ##Abundant
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) > n.Number;
GO
--------------------------------------------
--------------------------------------------
-- Deficient Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Deficient' AS NumberType
INTO ##Deficient
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) < n.Number;
GO
--------------------------------------------
--------------------------------------------
-- Perfect Numbers
WITH cte_Numbers AS
(
SELECT Number
FROM ##Numbers
WHERE Number = FLOOR(Number)
)
SELECT n.Number,
'Perfect' AS NumberType
INTO ##Perfect
FROM cte_Numbers n
WHERE n.Number > 1
AND (
SELECT SUM(d.Number)
FROM cte_Numbers d
WHERE d.Number > 0
AND d.Number < n.Number
AND n.Number % d.Number = 0
) = n.Number;
GO
--------------------------------------------
--------------------------------------------
-- Harshad (Niven) Numbers
WITH cte_Digits AS
(
SELECT n.Number,
CAST(SUBSTRING(s.Digits, v.n, 1) AS INT) AS Digit
FROM ##Numbers n
CROSS APPLY (SELECT CAST(ABS(n.Number) AS VARCHAR(20)) AS Digits) s
CROSS APPLY (SELECT TOP (LEN(s.Digits)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.objects) v
),
cte_DigitSums AS
(
SELECT Number,
SUM(Digit) AS DigitSum
FROM cte_Digits
GROUP BY Number
)
SELECT ds.Number,
'Harshad (Niven)' AS NumberType
INTO ##Harshad
FROM cte_DigitSums ds
WHERE ds.Number > 0 AND
ds.Number % ds.DigitSum = 0
ORDER BY ds.Number;
GO
--------------------------------------------
--------------------------------------------
-- Armstrong (Narcissistic) Numbers
WITH cte_Digits AS
(
SELECT n.Number,
LEN(CAST(ABS(n.Number) AS VARCHAR(20))) AS NumDigits,
CAST(SUBSTRING(s.Digits, v.n, 1) AS INT) AS Digit,
s.Digits,
v.n
FROM ##Numbers n CROSS APPLY
(SELECT CAST(ABS(n.Number) AS VARCHAR(20)) AS Digits) s CROSS APPLY
(SELECT TOP (LEN(s.Digits)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.objects) v
),
cte_DigitPowers AS
(
SELECT Number,
SUM(POWER(Digit, NumDigits)) AS DigitPowerSum
FROM cte_Digits
GROUP BY Number
)
SELECT dp.Number,
'Armstrong (Narcissistic)' AS NumberType
INTO ##Armstrong
FROM cte_DigitPowers dp
WHERE dp.Number = dp.DigitPowerSum AND
dp.Number >= 0
ORDER BY dp.Number;
GO
--------------------------------------------
--------------------------------------------
-- Factorial Numbers
WITH cte_Bound AS
(
SELECT CAST(ABS(MAX(CAST(Number AS BIGINT))) AS BIGINT) AS MaxAbs
FROM ##Numbers
),
cte_Factorials AS
(
SELECT 0 AS n,
CAST(1 AS DECIMAL(38,0)) AS Fact
FROM cte_Bound
UNION ALL
SELECT n + 1,
CAST(Fact * (n + 1) AS DECIMAL(38,0))
FROM cte_Factorials CROSS JOIN
cte_Bound
WHERE CAST(Fact * (n + 1) AS DECIMAL(38,0)) <= MaxAbs
)
SELECT DISTINCT
CAST(f.Fact AS BIGINT) AS Number,
'Factorial' AS NumberType
INTO ##Factorial
FROM cte_Factorials f INNER JOIN
(
SELECT DISTINCT CAST(Number AS DECIMAL(38,0)) AS NumberInt
FROM ##Numbers
WHERE Number >= 0 AND Number = FLOOR(Number)
) n
ON n.NumberInt = f.Fact
ORDER BY Number
OPTION (MAXRECURSION 32767);
GO
--------------------------------------------
--------------------------------------------
-- Results
SELECT
STRING_AGG(CONVERT(varchar(50), n.Number), ',') WITHIN GROUP (ORDER BY n.Number DESC) AS numbers,
COUNT(*) AS count,
oe.NumberType AS Even_Odd,
np.NumberType AS Negative_Positive,
id.NumberType AS Integer_Decimal,
w.NumberType AS Whole,
nat.NumberType AS Natural,
r.NumberType AS Real,
p.NumberType AS Prime,
c.NumberType AS Composite,
sq.NumberType AS Square,
cu.NumberType AS Cube,
fib.NumberType AS Fibonacci,
tri.NumberType AS Triangular,
pal.NumberType AS Palindromic,
ab.NumberType AS Abundant,
de.NumberType AS Deficient,
pe.NumberType AS Perfect,
h.NumberType AS Harshad,
a.NumberType AS Armstrong,
f.NumberType AS Factorial
INTO ##Result
FROM ##Numbers n
LEFT JOIN ##Odd_Even oe ON n.Number = oe.Number
LEFT JOIN ##Negative_Positive np ON n.Number = np.Number
LEFT JOIN ##Integer_Decimal id ON n.Number = id.Number
LEFT JOIN ##Whole w ON n.Number = w.Number
LEFT JOIN ##Natural nat ON n.Number = nat.Number
LEFT JOIN ##Real r ON n.Number = r.Number
LEFT JOIN ##Prime p ON n.Number = p.Number
LEFT JOIN ##Composite c ON n.Number = c.Number
LEFT JOIN ##Square sq ON n.Number = sq.Number
LEFT JOIN ##Cube cu ON n.Number = cu.Number
LEFT JOIN ##Fibonacci fib ON n.Number = fib.Number
LEFT JOIN ##Triangular tri ON n.Number = tri.Number
LEFT JOIN ##Palindromic pal ON n.Number = pal.Number
LEFT JOIN ##Abundant ab ON n.Number = ab.Number
LEFT JOIN ##Deficient de ON n.Number = de.Number
LEFT JOIN ##Perfect pe ON n.Number = pe.Number
LEFT JOIN ##Harshad h ON n.Number = h.Number
LEFT JOIN ##Armstrong a ON n.Number = a.Number
LEFT JOIN ##Factorial f ON n.Number = f.Number
GROUP BY
oe.NumberType,
np.NumberType,
id.NumberType,
w.NumberType,
nat.NumberType,
r.NumberType,
p.NumberType,
c.NumberType,
sq.NumberType,
cu.NumberType,
fib.NumberType,
tri.NumberType,
pal.NumberType,
ab.NumberType,
de.NumberType,
pe.NumberType,
h.NumberType,
a.NumberType,
f.NumberType
ORDER BY 2,1;
GO
--Concat
SELECT SUM(count) AS [Count],
Numbers,
CONCAT_WS(', ',Even_Odd,Negative_Positive,Integer_Decimal,Whole,Natural,[Real],Prime,Composite,[Square],[Cube],Fibonacci,Triangular,Palindromic,Abundant,Deficient,Perfect)
FROM ##Result
GROUP BY Numbers,
CONCAT_WS(', ',Even_Odd,Negative_Positive,Integer_Decimal,Whole,Natural,[Real],Prime,Composite,[Square],[Cube],Fibonacci,Triangular,Palindromic,Abundant,Deficient,Perfect)
ORDER BY 1,2;
GOHappy coding!
