0
votes

Avoir du mal à enrouler la tête autour de la façon d'écrire une boucle particulière

Je interrogee une base de données SQL pour retourner les opérations de commande de travail ouverte.
Ma requête produit le numéro de commande de travail, l'état de l'opération et la date d'échéance.
J'essaie de comprendre comment itération à travers le tableau qui est retourné et:

  • Rassemblez la somme des opérations dus dans une semaine li>
  • Rassemblez la somme des opérations dus dans la deuxième semaine li>
  • Continuez à faire cela jusqu'à ce que je vous ayez effectué toutes les entrées, en cours depuis autant de semaines que nécessaire. Li> ul>

    Ma requête SQL ressemble à quelque chose comme: p> xxx pré>

    Il retournera quelque chose comme: p>

    W/O #   | Setup Hours  |  Run Hours  |  Due Date
    W159769 |     0.5      |    15.0     | 03/01/2020
    W159770 |     1.5      |     9.0     | 04/01/2020
    W159771 |     0.75     |    81.0     | 05/01/2020
    


2 commentaires

Je suis un peu confus par la corrélation entre les dates d'échéance dans votre exemple de table et la sortie attendue. Les dates d'échéance sont un mois à part. Voulez-vous dire de les faire une semaine de distance?


Prenez un moment pour lire via le Aide d'édition dans le centre d'aide. Le formatage sur le débordement de la pile est différent de celui des autres sites. Mieux vaut votre message, plus il est facile pour les autres de la lire et de la comprendre.


5 Réponses :


2
votes

Je ne pense pas que vous ayez besoin d'une boucle. On dirait que vous pouviez simplement calculer le numéro de la semaine, le groupe par cela et la somme des heures de la semaine.

mysql strong> p>

select
  DATEDIFF(wk, getdate(), due_date) AS week_number,
  SUM(setup_hours + run_hours) AS week_hours
from operation
where resource_id = '280LASERS'
group by DATEDIFF(wk, getdate(), due_date);


8 commentaires

J'essaie d'exécuter ce code dans Microsoft SQL Server Management Studio et je reçois cette erreur: "'' Maintenant 'n'est pas un nom de fonction intégré reconnu."


D'accord, j'ai échangé maintenant () pour Current_TimeStamp et que DaturgIff nécessite 3 arguments.


D'accord, j'ai changé cette ligne à "DaturdeIff (Semaine, Work_Order.Desired_Want_Date, Current_TimeStamp) comme week-end_number" et je commence lentement quelque part.


Oh, Oops, c'est SQL Server. J'avais supposé MySQL car il est si souvent avec PHP. Je vous recommanderais de marquer vos questions relatives à la base de données avec le système spécifique que vous utilisez.


J'aimerais avoir compris comment convertir cela et le faire fonctionner car cela est beaucoup plus propre et plus simple. Merci pour votre participation!


Je pourrais peut-être effectuer une version pour SQL Server. Je n'ai tout simplement pas eu le temps aujourd'hui de regarder à nouveau


@ Justin.mpc J'ai ajouté un exemple d'exemple différent de la réponse pour SQL Server


Merci beaucoup pour toute votre aide géniale



1
votes

Comme ne la panique n'a pas souligné les dates d'échéance, je pense que vous pourriez l'afficher dans un format DD / mm / aaaa et je vais travailler à partir de là. Je vais travailler avec une boucle de forach, mais je pense que la solution de panique pourrait être plus efficace.

Étapes: 1. Boucle à travers les valeurs et calculer l'heure de la date, 2. Comparez-le avec la date souhaitée 3. Ajoutez-le à la bonne somme p>

Remarques: le format de date est important, si les heures, les minutes et les secondes manquent que GetTimeStamp ajoute les valeurs actuelles pour eux P>

J'ai ajouté certains Tester les données basées sur ma compréhension du problème. P>

J'ai également ajouté une colonne due au cas au cas où une date est déjà passée à l'heure actuelle (). P>

Les contrôles de la boucle de Foreach Le si le temps d'entrée est inférieur à l'heure actuelle, cela signifie qu'il est past_due. p>

sinon, nous vérifions si les futurs_dues sont définis. Les futures cotisations représentent toutes les semaines différentes à l'avenir. Si aucun n'est défini, un tableau avec un tableau est ajouté. Le deuxième tableau représente l'avenir le plus proche actuel à partir de l'heure actuelle à la fin de 7 jours à l'avenir. P>

Démarrer et fin Aidez-nous à mieux lire les résultats finaux, ce sont des horodatages. Aussi une clé de somme de valeur 0 est ajoutée. P>

Nous prenons ensuite le dernier élément des futifs_dues et voyons si le dust_date est plus petit que la fin de la semaine. Si c'est que nous ajoutons l'heure de travail, sinon nous ajoutons un nouvel objet futur_due. P>

à la fin J'ai ajouté une boucle de foresach qui convertit les horodatapes à un format de date. P>

$results=array(
  array( 'due_date'=>'12/02/2020', 'run_hours'=>12.4, 'setup_hours'=>2.4, ), //  2020-02-12 00:00:00
  array( 'due_date'=>'15/02/2020', 'run_hours'=>10.4, 'setup_hours'=>1.4, ), //  2020-02-15 00:00:00
  array( 'due_date'=>'18/02/2020', 'run_hours'=>8.4, 'setup_hours'=>3.4, ), //  2020-02-18 00:00:00
  array( 'due_date'=>'20/02/2020', 'run_hours'=>2.4, 'setup_hours'=>1.4, ), //  2020-02-20 00:00:00
  array( 'due_date'=>'21/02/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ), //  2020-02-21 00:00:00
  array( 'due_date'=>'24/02/2020', 'run_hours'=>12.4, 'setup_hours'=>1.4, ), //  2020-02-24 00:00:00
  array( 'due_date'=>'26/02/2020', 'run_hours'=>11.3, 'setup_hours'=>1.4, ), //  2020-02-26 00:00:00
  array( 'due_date'=>'29/02/2020', 'run_hours'=>4.4, 'setup_hours'=>2.4, ), //  2020-02-29 00:00:00
  array( 'due_date'=>'02/03/2020', 'run_hours'=>5.7, 'setup_hours'=>4, ), //  2020-03-02 00:00:00
  array( 'due_date'=>'04/03/2020', 'run_hours'=>11.5, 'setup_hours'=>3.4, ), //  2020-03-04 00:00:00
  array( 'due_date'=>'06/03/2020', 'run_hours'=>7.3, 'setup_hours'=>1.4, ), //  2020-03-06 00:00:00
  array( 'due_date'=>'08/03/2020', 'run_hours'=>9.6, 'setup_hours'=>1.4, ), //  2020-03-08 00:00:00
  array( 'due_date'=>'12/03/2020', 'run_hours'=>14.7, 'setup_hours'=>1.4, ), //  2020-03-12 00:00:00
  array( 'due_date'=>'15/03/2020', 'run_hours'=>12.5, 'setup_hours'=>1.4, ), //  2020-03-15 00:00:00
  array( 'due_date'=>'19/03/2020', 'run_hours'=>4.4, 'setup_hours'=>1.4, ), //  2020-03-19 00:00:00
  array( 'due_date'=>'21/03/2020', 'run_hours'=>5.6, 'setup_hours'=>4, ), //  2020-03-21 00:00:00
  array( 'due_date'=>'24/03/2020', 'run_hours'=>11.4, 'setup_hours'=>1.4, ), //  2020-03-24 00:00:00
  array( 'due_date'=>'29/03/2020', 'run_hours'=>7.4, 'setup_hours'=>1.4, ), //  2020-03-29 00:00:00
  array( 'due_date'=>'01/04/2020', 'run_hours'=>9.4, 'setup_hours'=>1.4, ), //  2020-04-01 00:00:00

);
$time=strtotime(date('Y-m-d')); // get time in same
// wrapping time in strtotime and date trims the seconds to the desired format

$one_week=60*60*24*7;
$sums=array();
foreach($results as $row){
 $date = DateTime::createFromFormat('d/m/Y', $row['due_date']);//use your format and values
 if(!$date){
  echo 'Not a valid format';
  break;
 }
 $entry_time = strtotime(date('Y-m-d',$date->getTimestamp()));
 // if your date format doesnt have hours minutes and seconds then timestamp will add the current h,min,s,
 // this may not be desired, so this wrapping it in strtotime and date trims the values
 $entry_work_hours=$row['run_hours']+$row['setup_hours'];
 if ($entry_time < $time) {
   if (isset($sums['future_dues'])) {
     $sums['past_due']['sum']+=$entry_work_hours;
   } else {
     $sums['past_due']= array(
      'sum'=> $entry_work_hours,
      'start'=> $row['due_date'],
      'end' => date('d/m/Y',$time),
     );
   }
 } else if ( $entry_time > $time ){
   if (isset($sums['future_dues'])) {
     $future_dues=$sums['future_dues'];
   } else {
     $future_dues = array(
       array(
         'sum'=>0,
         'start'=>$time,
         'end'=>$time+$one_week
       )
     );
   }
   $last_index = count($future_dues)-1;
   $future_due = $future_dues[$last_index];
   if ($entry_time < $future_due['end']) {
     $future_due['sum']+=$entry_work_hours;
     $future_dues[$last_index]=$future_due;
   } else {
     $future_dues[]=array(
       'sum'=>$entry_work_hours,
       'start'=>$future_due['end'],
       'end'=>$future_due['end']+$one_week
     );
   }
   $sums['future_dues']=$future_dues;
 }
}
// if you want to conver them back to dates
foreach ($sums['future_dues'] as $key => &$due) {
  $due['start']=date('d/m/Y',$due['start']);
  $due['end']=date('d/m/Y',$due['end']);
}


3 commentaires

Hé là-bas, j'apprécie votre réponse, je lis à travers cela et j'essaie de tout comprendre, je vous répondrai quand je suis terminé. Merci encore!


Alors, je pense que je l'ai compris, j'ai branché toutes mes informations. Je ne suis pas sûr que je dois faire écho après l'écho, pour obtenir des résultats postés sur la page ...


D'accord, je pourrais utiliser une certaine aide, j'ai PHP 5.2.1, ne savait pas que ce serait un problème, la plupart de votre code est incompatible (c'est-à-dire DateTime :: CreatefromFormat). Est-il possible pour vous de fournir l'alternative à ce code?



-1
votes

D'accord, voici le code que j'ai jusqu'à présent. J'aimerais que cela ait l'air mieux, peut-être pas montrer tous les éléments différents de la matrice ... mais je suis terrifié de changer beaucoup plus.

Ceci est un code assez incroyable aussi loin que moi. P>

5.26

2020/02/27
Array ( [sum] => 9.26 [start] => 2020/02/27 [end] => 2020/03/05 )
Array ( [sum] => 7.31 [start] => 2020/03/05 [end] => 2020/03/12 )
Array ( [sum] => 6.27 [start] => 2020/03/12 [end] => 2020/03/19 )
Array ( [sum] => 2.14 [start] => 2020/03/19 [end] => 2020/03/26 )
Array ( [sum] => 11.82 [start] => 2020/03/26 [end] => 2020/04/02 )
Array ( [sum] => 6.95 [start] => 2020/04/02 [end] => 2020/04/09 )
Array ( [sum] => 36 [start] => 2020/04/09 [end] => 2020/04/16 )
Array ( [sum] => 0.81 [start] => 2020/04/16 [end] => 2020/04/23 )
Array ( [sum] => 30.98 [start] => 2020/04/23 [end] => 2020/04/30 )
Array ( [sum] => 1.3 [start] => 2020/04/30 [end] => 2020/05/07 )
Array ( [sum] => 3.29 [start] => 2020/05/07 [end] => 2020/05/14 )
Array ( [sum] => 1.57 [start] => 2020/05/14 [end] => 2020/05/21 )
Array ( [sum] => 1.95 [start] => 2020/05/21 [end] => 2020/05/28 )
Array ( [sum] => 0.29 [start] => 2020/05/28 [end] => 2020/06/04 )
Array ( [sum] => 2.19 [start] => 2020/06/04 [end] => 2020/06/11 )
Array ( [sum] => 1.57 [start] => 2020/06/11 [end] => 2020/06/18 )
Array ( [sum] => 1.95 [start] => 2020/06/18 [end] => 2020/06/25 )
Array ( [sum] => 1.3 [start] => 2020/06/25 [end] => 2020/07/02 )
Array ( [sum] => 3.29 [start] => 2020/07/02 [end] => 2020/07/09 )
Array ( [sum] => 0.67 [start] => 2020/07/09 [end] => 2020/07/16 )
Array ( [sum] => 0.33 [start] => 2020/07/16 [end] => 2020/07/23 )
Array ( [sum] => 2.73 [start] => 2020/07/23 [end] => 2020/07/30 )
Array ( [sum] => 17.79 [start] => 2020/07/30 [end] => 2020/08/06 )
Array ( [sum] => 1.57 [start] => 2020/08/06 [end] => 2020/08/13 )
Array ( [sum] => 1.95 [start] => 2020/08/13 [end] => 2020/08/20 )
Array ( [sum] => 1.3 [start] => 2020/08/20 [end] => 2020/08/27 )
Array ( [sum] => 3.29 [start] => 2020/08/27 [end] => 2020/09/03 )
Array ( [sum] => 1.3 [start] => 2020/09/03 [end] => 2020/09/10 )
Array ( [sum] => 3.29 [start] => 2020/09/10 [end] => 2020/09/17 )
Array ( [sum] => 1.57 [start] => 2020/09/17 [end] => 2020/09/24 )
Array ( [sum] => 1.95 [start] => 2020/09/24 [end] => 2020/10/01 )  


0 commentaires

1
votes

Alors je suis de retour, j'ajouterai un meilleur code commenté, ici: Impossible de modifier l'ancienne réponse, car j'ai supprimé mon compte et j'ai oublié d'annuler: |

De toute façon, vous avez demandé comment manipuler le Les données. C'est un tableau simple et tous les tableaux intérieurs sont des sommes du début de la semaine jusqu'à la fin. Maintenant, vous pouvez les stocker avec des clés différentes, je viens d'utiliser l'attribution par défaut en raison de la simplicité. P>

$time=strtotime(date('Y-m-d'));

//to

$time=__TIME__YOU_WANT_IN_SECONDS__;

//or

$time = strtotime(__THE_DATE_YOU_WANT__); // eg. 01/01/2020
// now this is the time to compare all other dates to


6 commentaires

Merci encore pour la réponse, ce code est un travail génial. Le seul endroit où je rencontre des ennuis est avec les semaines qui n'ont pas encore de valeur. Par exemple, nous avons déjà commandé des commandes pour 0/4/2020 mais aucun entre les 20/04/2020 et le 6/3/2020, de sorte que la sortie des semaines entre les sorties fixes (il ne saute pas des semaines vides) et Tirez la première entrée de la prochaine semaine prévue, causant de nombreux problèmes. Donc, je peux utiliser les données jusqu'à ce point, mais alors tout est incorrect.


Aha ok je vois me donner une minute ou deux


Hey, qu'est-ce que la journée se déroulerait par une? Il dit qu'il se termine le 03/06 pourtant, il se termine en réalité le 03/05. Je pense avoir besoin d'un +1 quelque part mais je ne peux pas le voir.


P.s. Il semble se fixer après cette première itération. Le passé dû est donc correct, la première semaine de la semaine est de -1 jour, la deuxième semaine de la semaine est de +1 jour, puis tous les chiffres sur les semaines de procédure sont corrects.


JE L'AI FAIT! Le problème était avec cette ligne: si ($ entrée_time <$ dollar fudu_due ['fin']) {.... Je l'ai changé si ($ entrée_Time <= $ fuler_due ['fin']) {.... et ça Maintenant, c'est bien capturer le dernier jour de chaque semaine avant de continuer!


Est-il possible de faire quelque chose dans le sens de: si aujourd'hui - 01/01/2020 est divisible par 6 $ Last_index = comptage (futur_dues) - 6; Sinon si est divisible par 5 $ Last_index = comptage (Future_Dues) - 5;



0
votes

code SQL semble me procurer de bonnes informations, voici la version finale de
sélectionner Datrodiff (semaine, getDate (), work_order.desired_want_date) comme week_number, Somme (opération.setup_hrs + opération.run_hrs) comme semaine_hours De l'opération Rejoignez Work_order sur Operating.workorder_Base_ID = work_order.base_id Où opération.resource_id = '103Tourrette' et (opération.status = 'r' ou opération.status = 'f') et work_order.sub_id = '0' Groupe par daturade (semaine, getDate (), work_order.desired_want_date) Ordre par semaine_number; code>

me donne p>

week_number    week_hours
-14              0.630
-11              1.640
-8               1.980
-1               0.540
0                3.820
1                18.500
2                15.090
3                3.410
5                16.490
7                0.890
9                17.950
14               5.000
19               5.000
23               6.750
27               5.000
31               5.000


0 commentaires