|
Posted by Ed Murphy on 03/21/07 16:25
Henrik Juul wrote:
> I have the following 2 tables:
>
> (BATCHES)
> BatchID [int] KEY
> ID [int]
The 'ID' column should be renamed to indicate what it's an ID for.
> OrderID [int]
> Action1DateTime [datetime]
> Action2DateTime [datetime]
> Action3DateTime [datetime]
> Action4DateTime [datetime]
> Action5DateTime [datetime]
> Action6DateTime [datetime]
> Action7DateTime [datetime]
> Action8DateTime [datetime]
This is a classic case of bad design. Here's how to fix the design:
create view BatchesNormalized as
select BatchID, ID, OrderID,
Action1DateTime as ActionDateTime,
1 as ActionNumber -- if order is important
from Batches
where Action1DateTime is not null
union
select BatchID, ID, OrderID,
Action2DateTime as ActionDateTime,
2 as ActionNumber
from Batches
where Action2DateTime is not null
-- similar for 3 through 8
Ideally, you should fix the original table:
1) Create the view shown above
2) Copy its contents to a second table
3) Drop the view
4) Drop the Batches table and re-create it with the same columns
as the view
5) Copy the contents of the second table to the new Batches table
If you already have a lot of code referencing the non-normalized table:
1) Create the view
2) Change SELECTs one at a time to use the view
3) Create stored procedures that wrap around INSERT, UPDATE, and DELETE
4) Change INSERTs/UPDATEs/DELETEs one at a time to use the stored
procedures
5) Fix the table as described above, and at the same time, change the
stored procedure wrappers to use the fixed table
If you can't get rid of the non-normalized table (e.g. you're working
with a third-party software package), then at least create the view and
use it in your own stuff.
> (ORDERS)
> OrderID [int] KEY
> ProductionLineID [int]
> RecipeID [int]
> OrderAmount [int]
>
> Batches.Action1DateTime to Batches.Action8DateTime can have several entries
> each day.
> I need a query to count all Batches.Action1DateTime to all
> Batches.Action8DateTime for each day in a specified period.
> I also need to specifically use where clauses for Orders.OrderID and/or
> Orders.RecipeID.
Once the data is normalized, it becomes simple:
select b.ActionDateTime, count(*)
from BatchesNormalized b
join Orders o on b.OrderID = o.OrderID
where b.OrderID = @OrderID and o.RecipeID = @RecipeID
group by b.ActionDateTime
[Back to original message]
|