Personally, I'd go about it slightly differently.
For each unit in any given dimension, store its size in a common unit.
- I'd use a common size in meters
- For sake of copying your example, I've given everything in inches
Then, it's just a case of taking all combinations of units in the same dimension and to convert from A to B you simply multiply by the size of A and divide by the size of B.
For example...
Raw Data:
CREATE TABLE unit_dimension(
id INT IDENTITY(1,1) NOT NULL,
name NVARCHAR(32) NOT NULL,
);
INSERT INTO unit_dimension(name) VALUES ('distance'), ('time');
CREATE TABLE unit(
id INT IDENTITY(1,1) NOT NULL,
name NVARCHAR(32) NOT NULL,
plural NVARCHAR(32) NOT NULL,
symbol NVARCHAR(32) NOT NULL,
dimension_id INT NOT NULL,
size FLOAT NOT NULL
);
INSERT INTO
unit(name, plural, symbol, dimension_id, size)
VALUES
(N'Inch', N'Inches', N'in', 1, 1.00),
(N'Foot', N'Feet', N'ft', 1, 12.00),
(N'Yard', N'Yards', N'yd', 1, 36.00),
(N'Mile', N'Miles', N'mi', 1, 63360.00),
(N'Meter', N'Meters', N'm', 1, 39.37007874015748),
(N'Light Year', N'Light Years', N'ly', 1, 9460730472580800.00),
(N'Angrstom', N'Angstroms', N'Å', 1, 3.937007874e-9)
;
Actual UOMC, as a view...
CREATE VIEW v_UOMC AS
SELECT
x.id AS from_id,
x.name AS from_name,
y.id AS to_id,
y.name AS to_name,
x.size / y.size AS conversion_factor
FROM
unit x
INNER JOIN
unit y
ON x.dimension_id = y.dimension_id
;
Use thereof...
-- If I were to walk 5000 miles, how far would that be in meters?
SELECT
5000 * conversion_factor
FROM
v_UOMC
WHERE
from_name = 'Mile'
AND to_name = 'Meter'
;
EDIT:
To do a little leg work for the OP, this is the same answer using their EXACT table (including corrections to their script)...
CREATE TABLE [UOMC](
[From] [nchar](10) NULL,
[To] [nchar](10) NULL,
[Conv] [int] NULL,
[PrimaryUOM] [nchar](10) NULL,
[ConvToPrimary] [int] NULL
)
;
INSERT INTO [UOMC]
([From],[To],[Conv],[PrimaryUOM],[ConvToPrimary])
VALUES
('Feet','Inches',12,'Inches',12),
('Yards','Feet',3,'Inches',36),
('Miles','Yards',1760,'Inches',63360)
;
SELECT
x.[From] AS [From],
y.[From] AS [To],
x.ConvToPrimary * 1.0 / y.ConvToPrimary AS Conv,
x.ConvToPrimary AS ConvToPrimary
FROM
UOMC x
INNER JOIN
UOMC y
ON x.PrimaryUOM = y.PrimaryUOM
EDIT:
Or even...
WITH
UOMC_expanded AS
(
SELECT * FROM UOMC
UNION ALL
SELECT PrimaryUOM, PrimaryUOM, 1, PrimaryUOM, 1 FROM UOMC GROUP BY PrimaryUOM
)
SELECT
x.[From] AS [From],
y.[From] AS [To],
x.ConvToPrimary * 1.0 / y.ConvToPrimary AS Conv,
x.PrimaryUOM AS PrimaryUOM,
x.ConvToPrimary AS ConvToPrimary
FROM
UOMC_expanded x
INNER JOIN
UOMC_expanded y
ON x.PrimaryUOM = y.PrimaryUOM
ORDER BY
ConvToPrimary, Conv
Which gives...
From To Conv PrimaryUOM ConvToPrimary
Inches Miles 0.000015782828 Inches 1
Inches Yards 0.027777777777 Inches 1
Inches Feet 0.083333333333 Inches 1
Inches Inches 1.000000000000 Inches 1
Feet Miles 0.000189393939 Inches 12
Feet Yards 0.333333333333 Inches 12
Feet Feet 1.000000000000 Inches 12
Feet Inches 12.000000000000 Inches 12
Yards Miles 0.000568181818 Inches 36
Yards Yards 1.000000000000 Inches 36
Yards Feet 3.000000000000 Inches 36
Yards Inches 36.000000000000 Inches 36
Miles Miles 1.000000000000 Inches 63360
Miles Yards 1760.000000000000 Inches 63360
Miles Feet 5280.000000000000 Inches 63360
Miles Inches 63360.000000000000 Inches 63360