2010-12-02 9 views
0

Il semblerait qu'il existe une façon beaucoup plus simple d'énoncer le problème. S'il vous plaît voir Edit 2, en suivant l'exemple de tableau.Grouper par exécution lorsqu'il n'y a pas de numéro d'exécution dans les données (était Montrer comment le changement de la longueur d'une production affecte le temps de construction)

J'ai un certain nombre de produits différents sur une ligne de production. J'ai la date à laquelle chaque produit est entré en production. Chaque produit a deux identifiants: numéro d'article et numéro de série J'ai le nombre total d'heures de travail pour chaque produit par numéro d'article et par numéro de série (ie je peux vous dire combien d'heures sont passées dans chaque objet fabriqué et quelle est la moyenne le temps est pour chaque type d'objet).

Je veux déterminer comment (si) la variation de la longueur des cycles de production affecte le temps moyen nécessaire pour construire un produit (numéro d'article). Un cycle de production est la production séquentielle de plusieurs numéros de série pour un seul numéro d'article. Nous avons des enregistrements historiques remontant à plusieurs années avec des séries de production variant en longueur de 1 à 30.

Je pense que pour y parvenir, je dois être en mesure d'assigner 'run id'. Pour moi, cela signifie construire une requête qui trie par date de début et calcule une nouvelle valeur unique à chaque changement de numéro d'article. Si je savais comment faire cela, je pourrais résoudre le reste du problème par moi-même.

Alors qui suggère une série de questions connexes:

  1. Suis-je penser à ce la bonne voie?
  2. Si je suis sur la bonne voie, comment puis-je générer ces valeurs d'ID d'exécution? Calculer et stocker est une option, même si j'ai une préférence (égarée?) Pour les requêtes directes. Je sais exactement comment générer les numéros d'exécution dans Excel, mais j'ai une préférence (erronée?) Pour le faire dans la base de données.
  3. Si je ne suis pas sur la bonne voie, où puis-je trouver cette piste? :)

Edit: structure de tableau (simplifié) avec un échantillon de données:

AutoID Item  Serial  StartDate Hours  RunID (proposed calculation) 
1   Legend  1234  2010-06-06  10  1 
3   Legend  1235  2010-06-07  9  1 
2   Legend  1237  2010-06-08  8  1 
4   Apex  1236  2010-06-09  12  2 
5   Apex  1240  2010-06-10  11  2 
6   Legend  1239  2010-06-11  10  3 
7   Legend  1238  2010-06-12  8  3 

J'ai montré que la date de début, de série et sont mutuellement sans rapport avec identification automatique. J'ai montré l'attente que le travail diminue à mesure que la durée de la course augmente (mais c'est un 'fait' seulement par la sagesse reçue, pas par l'analyse des données). J'ai montré ce que je considère comme le cœur de la solution, étant un RunID qui reflète les constructions séquentielles d'un seul élément. Je sais que si je pouvais obtenir ce runID, je pourrais regrouper par course pour obtenir des comptes, des moyennes, des totaux, max, min, etc. En outre, je pourrais faire quelque chose comme heures/pour obtenir le changement de pourcentage depuis le début de la course. À ce moment-là, je pourrais représenter graphiquement les tendances associées à différentes durées de traitement, soit globalement pour tous les articles, soit pour chaque article. (Au moins, je pense que je pourrais faire tout ça, je devrais peut-être bouger un peu, mais je pense que je pourrais le faire.)

Éditer 2: Ce problème semble être: comment puis-je obtenir le ' débutant 'membre (première date de début) de chaque exécution quand je n'ai pas déjà un ID d'exécution? (Le RunId indiqué dans le tableau de l'échantillon n'existe pas et je l'origine suggère qu'être en mesure de calculer RunId était une solution potentiellement viable.)

AutoID Item 
1   Legend 
4   Apex 
6   Legend 

Je suppose que d'avoir appris comment trouver le premier membre de chaque fois que je serais en mesure d'utiliser ce que j'ai appris pour trouver le dernier membre de chaque course, puis utiliser ces deux résultats pour obtenir tous les autres membres de chaque course.

Édition 3: ma version d'une requête qui utilise l'AutoID du premier élément dans une exécution en tant que RunID pour toutes les unités d'une exécution.Cela a été construit entièrement à partir d'échantillons et de direction fournis par Simon, qui a la réponse acceptée. En utilisant ceci comme base pour le regroupement par exécution, je peux produire une variété de statistiques d'exécution.

SELECT first_product_of_run.AutoID AS RunId, run_sibling.AutoID AS itemID, run_sibling.Item, run_sibling.Serial, run_sibling.StartDate, run_sibling.Hours à partir de (SELECT first_of_run.AutoID, first_of_run.Item, first_of_run.Serial, first_of_run.StartDate , first_of_run.Hours DE dbo.production AS first_of_run LEFT OUTER JOIN dbo.production AS earlier_in_run SUR first_of_run.AutoID - 1 = earlier_in_run.AutoID ET first_of_run.Item = earlier_in_run.Item OU (earlier_in_run.AutoID IS NULL)) AS first_product_of_run GAUCHE OUTER JOIN dbo.production AS run_sibling SUR first_product_of_run.Item = run_sibling.Item ET premier_produit_of_run.AutoID run_sibling.AutoID ET first_product_of_run.StartDate product_between.Item AND first_product_of_run.StartDate

Répondre

1

Pourriez-vous décrire la structure de votre tableau un peu plus? Si la «date à laquelle chaque produit est entré en production» est un horodatage complet ou s'il existe un identifiant séquentiel sur plusieurs produits, vous pouvez écrire des requêtes pour identifier le premier et le dernier produit d'une analyse. De cela, vous pouvez assigner des ID ou calculer la longueur des courses.

Edit: Une fois que vous avez identifié 1,4, et 6 comme le début d'une course, vous pouvez utiliser cette requête pour trouver les autres ID dans la course:

select first_product_of_run.AutoID, run_sibling.AutoID 
from first_product_of_run 
left join production run_sibling on first_product_of_run.Item = run_sibling.Item 
    and first_product_of_run.AutoID <> run_sibling.AutoID 
    and first_product_of_run.StartDate < run_sibling.StartDate 
left join production product_between on first_product_of_run.Item <> product_between.Item 
    and first_product_of_run.StartDate < product_between.StartDate 
    and product_between.StartDate < run_sibling.StartDate 
where product_between.AutoID is null 

first_product_of_run peut être table temporaire, variable de table ou sous-requête que vous avez utilisée pour rechercher le début d'une exécution. La clé est le where product_between.AutoID is null. Cela limite les résultats aux paires seulement où aucun article différent n'a été produit entre eux.

Edit 2, voici comment obtenir le premier de chaque course:

select first_of_run.AutoID 
from 
(
select product.AutoID, product.Item, MAX(previous_product.StartDate) as PreviousDate 
from production product 
left join production previous_product on product.AutoID <> previous_product.AutoID 
    and product.StartDate > previous_product.StartDate 
group by product.AutoID, product.Item 
) first_of_run 
left join production earlier_in_run 
    on first_of_run.PreviousDate = earlier_in_run.StartDate 
    and first_of_run.Item = earlier_in_run.Item 
where earlier_in_run.AutoID is null 

Ce n'est pas assez, et briser si StartDate est pas unique. La requête pourrait être simplifiée en ajoutant un identifiant séquentiel et unique sans lacunes. En fait, cette étape sera probablement nécessaire si StartDate n'est pas unique. Voici à quoi il ressemblerait:

select first_of_run.AutoID 
from production first_of_run 
left join production earlier_in_run 
    on (first_of_run.Sequence - 1) = earlier_in_run.Sequence 
    and first_of_run.Item = earlier_in_run.Item 
where earlier_in_run.AutoID is null 

En utilisant les jointures externes pour trouver où les choses ne sont pas tord encore mon cerveau, mais il est une technique très puissante.

+0

@Simon: voir les éditions pour la structure de la table et d'autres précisions. Je sais identifier la première et la dernière date d'un article donné, mais je ne sais pas comment récupérer les articles pour une exécution donnée, principalement parce que je n'ai pas encore d'ID d'exécution. – jadero

+0

S'il n'est pas nécessaire que les ID d'exécution soient séquentiels, je recommande d'utiliser l'ID automatique du premier produit dans la série. – Simon

+0

@Simon: Vous m'avez aidé à voir exactement la question que je dois poser: comment identifier le «membre de départ» de chaque course? (Je suppose que je peux facilement modifier cela pour obtenir le «membre final» et ensuite combiner les résultats pour obtenir chaque membre.) Voir Edit 2 – jadero