web-dev-qa-db-fra.com

Comment déployez-vous des valeurs de niveau d'en-tête sur une table de fait avec la granularité d'élément de ligne?

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:

enter image description here

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?

  1. Le montant d'expédition est-il considéré comme un fait non additif pour ce tableau?
  2. Est-ce une sorte de manipulation spéciale requise?
  3. Y a-t-il des raisons de ne pas avoir deux tables de fait (presque identiques)? Un pour les commandes et une pour les articles de commande?
7
8kb

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.

4
Jamie

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.

2
Jon of All Trades

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 
2
Leigh Riffel

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.

2
Yasir