Besoin d'une aide sur Requete SQL

Eléphant du PHP | 440 Messages

29 mars 2011, 20:35

Bonsoir, je galère sur ma requête.
En fait j'ai une requête qui est composé d'un UNION ALL (2 requêtes)
SELECT     SUM(tt) AS tt,
	   SUM([count]) AS [count],
           SUM(ImpPCPMrec ) AS ImpPCPMrec,
           atelier,
           societe
FROM
(SELECT (SELECT coalesce (sum (ttotfichado.Tiempopasado),0)
     FROM  ttotfichado
     WHERE ttotfichado.hayabono<> 1 AND
           (NOT (ttOTFichado.RepartoPendiente = 0 AND ttOTFichado.FichajeContraOT > 0) OR ttOTFichado.RepartoPendiente IS NULL) AND
           ttOTIntervencion.Emp = ttOTFichado.Emp AND
           ttOTIntervencion.Numinterno = ttOTFichado.Numinterno AND  
           ttOTIntervencion.Intervencion = ttOTFichado.Intervencion AND
           ttotfichado.fecha <= '12-1-2011 23:59:59.000') AS tt, 
  Count(DISTINCT ttOTCab.NumOT) AS [count],
  SUM(case tipocab
    when 0 then
      case tipolinea
        when 1 then
          case ttOTIntervencion.esabono
            when 1 then (-1 * ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras))
            else             (ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras))
          end
        else 0
      end	
    else 0
  end) AS ImpPCPMrec,
  tgtaller.descrip AS atelier,
  tgempresa.razon AS societe
  
FROM ttoTCab
 
  INNER JOIN tgempresa ON
  ttotcab.emp = tgempresa.emp 
 
  INNER JOIN tgtaller ON
  ttotcab.emp = tgtaller.emp AND ttotcab.taller = tgtaller.taller
 
  INNER JOIN ttOTIntervencion ON 
  ttOTCab.Emp = ttOTIntervencion.Emp AND 
  ttOTCab.NumInterno = ttOTIntervencion.Numinterno 
 
  INNER JOIN ttOTLinea ON 
  ttOTIntervencion.Emp = ttOTLinea.Emp AND 
  ttOTIntervencion.Numinterno = ttOTLinea.NumIntOT AND 
  ttOTIntervencion.Intervencion = ttOTLinea.NumIntIntervencion 
 
  INNER JOIN ttSeccion ON 
  ttOTCab.Seccion = ttSeccion.Seccion 
 
  INNER JOIN ttSeccion seccion ON 
  ttOTIntervencion.Seccion = seccion.Seccion 
 
  LEFT OUTER JOIN TTrecepcionista ON
  ttOtCab.emp = TTrecepcionista.emp AND
  ttOtCab.taller = TTrecepcionista.taller AND 
  ttOtCab.recepcionista = TTrecepcionista.recepcionista
 
  LEFT OUTER JOIN Tgmarca ON
  ttOtCab.marca = tgmarca.marca
 
  LEFT OUTER JOIN ttOTCargoLinea ON 
  ttOTLinea.Emp = ttOTCargoLinea.Emp AND
  ttOTLinea.NumIntOT = ttOTCargoLinea.NumIntOT AND 
  ttOTLinea.NumIntIntervencion = ttOTCargoLinea.NumIntIntervencion AND
  ttOTLinea.LineaItem = ttOTCargoLinea.LineaItem 
 
  LEFT OUTER JOIN ttOTCargoInt ON
  ttOTCargoLinea.Emp = ttotcargoint.emp AND
  ttOTCargoLinea.NumIntOT = ttotcargoint.Numintot AND 
  ttOTCargoLinea.NumIntIntervencion = ttotcargoint.numintintervencion AND
  ttOTCargoLinea.NumIntcargo = ttotcargoint.numintcargo 
 
  LEFT OUTER JOIN ttotcargo ON
  ttotcargoint.emp=ttotcargo.emp AND 
  ttotcargoint.NumIntOT=ttotcargo.NumInterno AND
  ttotcargoint.NumIntCargo=ttotcargo.Cargo 
 
  LEFT OUTER JOIN ttgrupocargo ON
  ttOTCargo.grupocargo = ttgrupocargo.grupo
 
  LEFT OUTER JOIN tgGrupoCont ON 
  ttOTLinea.GrupoCont = tgGrupoCont.GrupoCont
 
  LEFT OUTER JOIN tgMarca MarcaLinea ON 
  ttOTLinea.Marca = MarcaLinea.Marca
 
  LEFT OUTER JOIN tacategoriapieza ON	
  ttotlinea.marca = tacategoriapieza.marca AND ttotlinea.codigocategoria 	= tacategoriapieza.codigo
  
  LEFT OUTER JOIN ttotstatus 	  ON ttOTCab.statusencurso = ttotstatus.Codigo
 
WHERE   
   (ttotcab.emp='002' ) AND  
	(ttotintervencion.hayfactura = 0 ) AND
	(ttotcab.taller='20' ) AND  
	(ttOTCab.Anulada = 0) AND 
	(ttOTLinea.Anulada = 0) AND 
   (ttOTCab.FechaAperturaOT <= '12-1-2011 23:59:59.000' ) AND  
	(
	   ttOTLinea.FechaAlta <= '12-1-2011 23:59:59.000'
		OR ttotlinea.tipocab =1
	) AND 	
	(ttotlinea.tipocab <> 2) AND 
   (ttOTCab.STATUS = 30 )  AND
(ttotlinea.cantidadhoras <> 0 OR ttotlinea.almservido <> 1)
GROUP BY tgempresa.razon, tgtaller.descrip, ttOTIntervencion.Emp, ttOTIntervencion.Numinterno,  ttOTIntervencion.Intervencion)
AS T
GROUP BY atelier,societe

UNION ALL


SELECT     
SUM(tt) AS tt, SUM([count]) AS [count],
           SUM(ImpPCPMrec ) AS ImpPCPMrec,
           atelier,
           societe
FROM
(SELECT (SELECT coalesce (sum (ttotfichado.Tiempopasado),0)
     FROM  ttotfichado
     WHERE ttotfichado.hayabono<> 1 AND
           (NOT (ttOTFichado.RepartoPendiente = 0 AND ttOTFichado.FichajeContraOT > 0) OR ttOTFichado.RepartoPendiente IS NULL) AND
           ttOTIntervencion.Emp = ttOTFichado.Emp AND
           ttOTIntervencion.Numinterno = ttOTFichado.Numinterno AND  
           ttOTIntervencion.Intervencion = ttOTFichado.Intervencion AND
           ttotfichado.fecha <= '12-1-2011 23:59:59.000') AS tt, 
   Count(DISTINCT ttOTCab.NumOT) AS [count],
 SUM( case tipocab
    when 0 then
      case tipolinea
        when 1 then
          case ttOTIntervencion.esabono
            when 1 then (-1 * ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras))
            else             (ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras))
          end
        else 0
      end
    else 0
  end) as ImpPCPMrec,

    tgtaller.descrip as atelier,
  tgempresa.razon as societe
FROM     
  ttOTCab
    LEFT OUTER JOIN tgmarca ON ttotcab.marca = tgmarca.marca
	 LEFT OUTER JOIN ttotstatus 	  ON ttOTCab.statusencurso = ttotstatus.Codigo
    LEFT OUTER JOIN ttrecepcionista ON ttOtCab.emp = TTrecepcionista.emp  and 
  ttOtCab.taller = TTrecepcionista.taller  and 
  ttOtCab.recepcionista = TTrecepcionista.recepcionista, 
  ttOTCargo, 
  ttOTCargoInt, 
  ttOTCargoLinea, 
  ttOTIntervencion,
  ttOTLinea
    LEFT OUTER JOIN tgGrupoCont ON tgGrupoCont.GrupoCont = ttOTLinea.GrupoCont
    LEFT OUTER JOIN tgMarca MarcaLinea ON ttOTLinea.Marca = MarcaLinea.Marca
	 LEFT OUTER JOIN tacategoriapieza ON ttotlinea.marca = tacategoriapieza.marca and ttotlinea.codigocategoria = tacategoriapieza.codigo,
  ttSeccion, ttOTFac, tgtaller, tgempresa, ttgrupocargo, ttSeccion seccion

WHERE 

  ttOTCargo.grupocargo = ttgrupocargo.grupo and 
  ttotfac.emp='002'  and 
  ttotcab.taller='20' and 
  ttotfac.abono<> 1 and	
  ttotfac.fechafactura > '12-1-2011 23:59:59.000' and 
  ttotcab.emp = tgempresa.emp and 
  ttotcab.emp = tgtaller.emp and 
  ttotcab.taller = tgtaller.taller and 
  ttotcargo.emp = ttotfac.emp and 
  ttotcargo.NumInterno = ttotfac.NumInterno and 
  ttotcargo.Cargo = ttotfac.NumIntCargo and 
  ttotcargoint.emp = ttotcargo.emp and 
  ttotcargoint.NumIntOT = ttotcargo.NumInterno and 
  ttotcargoint.NumIntCargo = ttotcargo.Cargo and 
  ttotcargoLinea.emp = ttotcargoint.emp and 
  ttotcargoLinea.NumIntOT = ttotcargoint.NumIntOT and 
  ttotcargoLinea.NumIntCargo = ttotcargoint.NumIntCargo and 
  ttotcargoLinea.NumIntIntervencion = ttotcargoint.NumIntIntervencion and 
  ttotlinea.emp = ttotcargoLinea.emp and 
  ttotlinea.NumIntOT = ttotcargoLinea.NumIntOT and 
  ttotlinea.NumIntIntervencion = ttotcargoLinea.NumIntIntervencion and 
  ttotlinea.LineaItem=ttotcargoLinea.LineaItem and 
    (
	  	ttOTLinea.FechaAlta <= '12-1-2011 23:59:59.000'  
		or 	ttotlinea.tipocab =1
	 ) and 
  ttotlinea.tipocab <> 2 and 
  ttotintervencion.emp = ttotlinea.emp and 
  ttotintervencion.Numinterno = ttotlinea.NumIntOT and 
  ttotintervencion.Intervencion = ttotlinea.NumIntIntervencion and 
  ttOTCab.Seccion = ttSeccion.Seccion and 
  ttOTIntervencion.Seccion = Seccion.SECCION and 
  ttotcab.emp = ttotintervencion.emp and 
  ttotcab.numinterno = ttotintervencion.Numinterno and
  ttotcab.fechaaperturaOT <= '12-1-2011 23:59:59.000' and
  ttotcab.status >=30  and
(ttotlinea.cantidadhoras <> 0 or ttotlinea.almservido <> 1)
group by  tgempresa.razon, tgtaller.descrip, ttOTIntervencion.Emp, ttOTIntervencion.Numinterno,  ttOTIntervencion.Intervencion ) AS T
GROUP BY atelier, societe


Voici ma requete, j'obtient ceci:

Code : Tout sélectionner

tt count IMp atelier societe 79.6100 20 2572.8880 ATELIER MECA1 EST AUTO 318.2600 112 7178.3320 ATELIER MECA1 EST AUTO
Tout est Correct sauf le count de la 2ème ligne (112) normalement je devrait retrouver 58.

J'ai testé la requête seul sans union, j'ai 112 au niveau du count.

Code : Tout sélectionner

SELECT (SELECT coalesce (sum (ttotfichado.Tiempopasado),0) FROM ttotfichado WHERE ttotfichado.hayabono<> 1 AND (NOT (ttOTFichado.RepartoPendiente = 0 AND ttOTFichado.FichajeContraOT > 0) OR ttOTFichado.RepartoPendiente IS NULL) AND ttOTIntervencion.Emp = ttOTFichado.Emp AND ttOTIntervencion.Numinterno = ttOTFichado.Numinterno AND ttOTIntervencion.Intervencion = ttOTFichado.Intervencion AND ttotfichado.fecha <= '12-1-2011 23:59:59.000') AS tt

Des que je retire la partie ci-dessus et les group by en trop (ttOTIntervencion.Emp, ttOTIntervencion.Numinterno, ttOTIntervencion.Intervencion)

Code : Tout sélectionner

SELECT count(DISTINCT (ttOTCab.NumOT)) as [count], SUM( case tipocab when 0 then case tipolinea when 1 then case ttOTIntervencion.esabono when 1 then (-1 * ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras)) else (ttotlinea.PrecioCosteMedio * coalesce (ttotcargolinea.cantidadhoras,ttotlinea.cantidadhoras)) end else 0 end else 0 end) as ImpPCPMrec, tgtaller.descrip as atelier, tgempresa.razon as societe FROM ttOTCab LEFT OUTER JOIN tgmarca ON ttotcab.marca = tgmarca.marca LEFT OUTER JOIN ttotstatus ON ttOTCab.statusencurso = ttotstatus.Codigo LEFT OUTER JOIN ttrecepcionista ON ttOtCab.emp = TTrecepcionista.emp and ttOtCab.taller = TTrecepcionista.taller and ttOtCab.recepcionista = TTrecepcionista.recepcionista, ttOTCargo, ttOTCargoInt, ttOTCargoLinea, ttOTIntervencion, ttOTLinea LEFT OUTER JOIN tgGrupoCont ON tgGrupoCont.GrupoCont = ttOTLinea.GrupoCont LEFT OUTER JOIN tgMarca MarcaLinea ON ttOTLinea.Marca = MarcaLinea.Marca LEFT OUTER JOIN tacategoriapieza ON ttotlinea.marca = tacategoriapieza.marca and ttotlinea.codigocategoria = tacategoriapieza.codigo, ttSeccion, ttOTFac, tgtaller, tgempresa, ttgrupocargo, ttSeccion seccion WHERE ttOTCargo.grupocargo = ttgrupocargo.grupo and ttotfac.emp='002' and ttotcab.taller='20' and ttotfac.abono<> 1 and ttotfac.fechafactura > '12-1-2011 23:59:59.000' and ttotcab.emp = tgempresa.emp and ttotcab.emp = tgtaller.emp and ttotcab.taller = tgtaller.taller and ttotcargo.emp = ttotfac.emp and ttotcargo.NumInterno = ttotfac.NumInterno and ttotcargo.Cargo = ttotfac.NumIntCargo and ttotcargoint.emp = ttotcargo.emp and ttotcargoint.NumIntOT = ttotcargo.NumInterno and ttotcargoint.NumIntCargo = ttotcargo.Cargo and ttotcargoLinea.emp = ttotcargoint.emp and ttotcargoLinea.NumIntOT = ttotcargoint.NumIntOT and ttotcargoLinea.NumIntCargo = ttotcargoint.NumIntCargo and ttotcargoLinea.NumIntIntervencion = ttotcargoint.NumIntIntervencion and ttotlinea.emp = ttotcargoLinea.emp and ttotlinea.NumIntOT = ttotcargoLinea.NumIntOT and ttotlinea.NumIntIntervencion = ttotcargoLinea.NumIntIntervencion and ttotlinea.LineaItem=ttotcargoLinea.LineaItem and ( ttOTLinea.FechaAlta <= '12-1-2011 23:59:59.000' or ttotlinea.tipocab =1 ) and ttotlinea.tipocab <> 2 and ttotintervencion.emp = ttotlinea.emp and ttotintervencion.Numinterno = ttotlinea.NumIntOT and ttotintervencion.Intervencion = ttotlinea.NumIntIntervencion and ttOTCab.Seccion = ttSeccion.Seccion and ttOTIntervencion.Seccion = Seccion.SECCION and ttotcab.emp = ttotintervencion.emp and ttotcab.numinterno = ttotintervencion.Numinterno and ttotcab.fechaaperturaOT <= '12-1-2011 23:59:59.000' and ttotcab.status >=30 and (ttotlinea.cantidadhoras <> 0 or ttotlinea.almservido <> 1) group by tgempresa.razon, tgtaller.descrip
Le résultat de la requête me retourne bien au niveau du count 58.


J'arrive pas a comprendre, je suis sur cette requête depuis début d’après midi mais sans résultat. Quelle erreur est-je commis ?

Merci d'avance pour votre aide.

guigui69

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

30 mars 2011, 15:50

Tu dois réviser les champs des group by car le nombre de champs dans un group by détermine le niveau réel du calcul effectué par Count(), Sum() etc.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 440 Messages

30 mars 2011, 17:46

C'est a dire réviser les champs ? Changer le positionnement dans le group by? Car je but.

ViPHP
xTG
ViPHP | 7331 Messages

30 mars 2011, 18:00

Je pense qu'il a voulu dire que tu devais réviser tes notions SQL quand à l'utilisation du GROUP BY. :wink:

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

30 mars 2011, 20:28

C'est a dire réviser les champs ? Changer le positionnement dans le group by? Car je but.
Je voulais dire : vérifier si les champs que tu mets dans tous les group by de tes sous-requêtes correspondent bien au niveau du regroupement où les calculs doivent se faire. Car compter, par exemple, le nombre total d'élèves d'une école n'est pas la même chose que compter le nombre d'élèves par classe dans la même école. Le nombre et l'ordre des champs du group by définissent logiquement le niveau des calculs attendus.

Mais puisque ça marche quand tu as viré "les group by en trop (ttOTIntervencion.Emp, ttOTIntervencion.Numinterno, ttOTIntervencion.Intervencion) alors il y a un problème de regroupement des tables de la deuxième requête de l'union.

Dans un premier temps regarde au niveau du FROM de la deuxième requête, celui-ci:
FROM
ttOTCab
LEFT OUTER JOIN tgmarca ON ttotcab.marca = tgmarca.marca
LEFT OUTER JOIN ttotstatus ON ttOTCab.statusencurso = ttotstatus.Codigo
LEFT OUTER JOIN ttrecepcionista ON ttOtCab.emp = TTrecepcionista.emp and
ttOtCab.taller = TTrecepcionista.taller and
ttOtCab.recepcionista = TTrecepcionista.recepcionista,
ttOTCargo,
ttOTCargoInt,
ttOTCargoLinea,
ttOTIntervencion,
ttOTLinea
LEFT OUTER JOIN tgGrupoCont ON tgGrupoCont.GrupoCont = ttOTLinea.GrupoCont
LEFT OUTER JOIN tgMarca MarcaLinea ON ttOTLinea.Marca = MarcaLinea.Marca
LEFT OUTER JOIN tacategoriapieza ON ttotlinea.marca = tacategoriapieza.marca and ttotlinea.codigocategoria = tacategoriapieza.codigo,
ttSeccion, ttOTFac, tgtaller, tgempresa, ttgrupocargo, ttSeccion seccion
C'est une erreur de mettre des tables sans aucune jointure avec les autres. Il s'agit des tables suivantes:
ttOTCargo,
ttOTCargoInt,
ttOTCargoLinea,
ttOTIntervencion,
Et d'ailleurs l'une d'entre-elles (ttOTIntervencion) est utilisée dans le GROUP BY. Et ça c'est une drôle de coïncidence. Et on sait que le fait de mettre une table sans jointure avec les autres dans un FROM risque de démultiplier les enregistrements des tables spécifiées en les croisant au lieu de faire une intersection (jointure).
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 440 Messages

01 avr. 2011, 21:05

Merci pour votre aide je vait regarder ca :)

guigui69