De ce que j'ai lu, la granularité recommandée pour une table de fait basée sur une structure d'en-tête de commande/ligne de ligne est au niveau de l'élément de la ligne. Dans le processus, toutes les valeurs additives qui s'appliquent uniquement à l'en-tête de commande sont répétées pour chaque élément de ligne:
concevoir des modèles dimensionnels pour les applications parent-enfant
bases de modélisation dimensionnelle
Ci-dessous (à partir du deuxième lien) est un exemple d'un tel design:
Dans cet exemple, le montant d'expédition, qui s'applique à l'ordre dans son ensemble, répète pour chaque élément de ligne.
Mais si vous deviez rouler tous les montants d'expédition sous un client spécifique, vous auriez double la valeur réelle. Comment évitez-vous ce doublement de la valeur?
J'introduisais un produit d'expédition magique et mettez la valeur de l'expédition à ce sujet uniquement (laissant Ouvrir la possibilité d'avoir plusieurs produits d'expédition trop - lourd/nuit/etc.). Je garderais probablement toujours le shoppingAmount séparé de la colonne de producteur, afin que vous puissiez facilement ajouter des ventes de produits uniquement.
Si possible, j'allouerais les frais d'expédition aux éléments de ligne. Cela vous permettrait d'évaluer le coût et des bénéfices réels pour des produits individuels aussi précisément que possible.
Si cela n'est pas possible, j'ai deuxième @ Jamie l'idée de faire Shipping
un type spécial de "produit".
Ceci est discuté par KIMBALL dans la boîte à outils de données Warehouse (troisième édition), mais il fait une recommandation légèrement différente:
Si les frais d'expédition et les autres faits au niveau de l'en-tête ne peuvent pas être attribués avec succès, ils doivent être présentés dans une table globale pour l'ordre général. Nous préférons clairement l'approche d'allocation, si possible, car la table de fait de niveau supérieure séparée a des problèmes de convivialité inhérents. Sans allocation, vous ne pouvez pas explorer les faits d'en-tête par produit car le produit n'est pas identifié dans une table de fait grain d'en-tête.
Comment évitez-vous ce doublement de la valeur?
Vous pouvez le faire en regroupant d'abord par le groupe de commandes, puis regrouper par la citoyenneté. Voici un exemple:
--Setup.
DROP TABLE OrderLineItems;
CREATE TABLE OrderLineItems AS (
SELECT 27 CustomerKey, 7867 OrderNumber, 49.98 OrderAmount
, 3 ShippingAmount FROM dual);
INSERT INTO OrderLineItems VALUES (27,7867,12.99,3);
INSERT INTO OrderLineItems VALUES (39,7868,1321.99,132);
INSERT INTO OrderLineItems VALUES (19,7869,39.99,6);
INSERT INTO OrderLineItems VALUES (19,7870,1321.99,132);
COMMIT;
--Query.
SELECT CustomerKey, sum(OrderAmount), sum(ShippingAmount) FROM (
SELECT CustomerKey, OrderNumber, sum(OrderAmount) OrderAmount
, MIN(ShippingAmount) ShippingAmount
FROM OrderLineItems
GROUP BY CustomerKey, OrderNumber
)
GROUP BY CustomerKey;
CUSTOMERKEY SUM(ORDERAMOUNT) SUM(SHIPPINGAMOUNT)
----------- ---------------- -------------------
27 62.97 3
39 1321.99 132
19 1361.98 138
Vous pouvez diviser les frais d'expédition de manière égale parmi les lignes de commande. Cela vous permettra de vous déplacer par le client.