Search code examples
sql-serverviewunionnormalize

SQL Server views - simulating a table from a normalized source


Alright, so I have a table that I need to store in a database. The table is in the following format:

Value  | No Deductible | $100 | $250 | $500 |
=============================================
$20000 |          $122 |  $61 |  $28 |  N/A |
$30000 |          $183 | $117 |  $67 |  $44 |

To make it normalized and easily accessible, the table will be in the following format in the SQL Server database:

Value (PK)  | Deductible (PK) | Cost |
======================================
     $20000 |              $0 | $122 | 
     $20000 |            $100 |  $61 |  

The Value and Deductible columns are a joint primary key, preventing duplicates. Additionally there will be a constraint only allow certain deductible values.

Now, this format is perfect for accessibility, but it's obviously not easy to insert data into. I don't have immediate plans to build a logical front end for it, so a view in this scenario would be ideal. However, my attempts to produce a view that I can easily edit have failed.

Try 1

SELECT 
    t1.Value, t2.Cost AS [No Deductible], 
    t3.Cost AS [$100], t4.Cost AS [$250], t5.Cost AS [$500]
FROM  Valuation AS t1 
INNER JOIN Valuation AS t2 ON t1.Value = t2.Value 
INNER JOIN Valuation AS t3 ON t2.Value = t3.Value 
INNER JOIN Valuation AS t4 ON t3.Value = t4.Value 
INNER JOIN Valuation AS t5 ON t1.Value = t5.Value
WHERE  
    (t2.Deductible = 0) AND (t3.Deductible = 100) 
    AND (t4.Deductible = 250) AND (t5.Deductible = 500)  

This doesn't work because you can't modify multiple base tables.

Try 2

SELECT Value, 
   (SELECT Cost FROM Valuation WHERE Deductible = 0) AS [No Deductible],
   (SELECT Cost FROM Valuation WHERE Deductible = 100) AS [$100],
   (SELECT Cost FROM Valuation WHERE Deductible = 250) AS [$250],
   (SELECT Cost FROM Valuation WHERE Deductible = 500) AS [$500]
FROM Valuation 
GROUP BY Value

You can't modify calculated columns, either.

Is there an elegant solution to this problem? Perhaps something with unions? I feel like the only solutions I have now are to produce multiple views for each deductible, keep the original table layout (a possibility but not preferred, as the value/deductible key is used as a foreign key in other tables) or just invest the time into creating the logical front end to simulate the table (which, as I said, I would prefer to do later).


Solution

  • First another choice for the query would be:

    Select Value
        , Min( Case When Deductible = '0' Then Cost End ) As [No Deductible]
        , Min( Case When Deductible = '100' Then Cost End ) As [$100]
        , Min( Case When Deductible = '250' Then Cost End ) As [$250]
        , Min( Case When Deductible = '500' Then Cost End ) As [$500]
    From Valuation
    Group By Value
    

    However, this will not enable the view to be updateable. The only way to make it updateable is to add a InsteadOf trigger that will re-normalize the inputted rows in the view structure back to their normalized storage format.