2009-01-28 7 views
1

La requête SQL Server J'est:SQL somme avec la différence

SELECT 
    ep.employeeID, ep.punchdate, rc.creditAmount 
FROM 
    EmployeePunch ep 
    INNER JOIN 
     ResponderCredit rc ON rc.employeeID = ep.employeeID AND 
     rc.punchdate = rc.creditdate 
ORDER BY ep.employeeID 

et obtenir un jeu de résultats:

EmployeeID  Date    CreditAmount 
----------- -------   -------------- 
    5    01/01/2007    5 
    5    03/01/2007    7 
    5    04/22/2007    15 
    6    01/01/2007    3 
    6    01/12/2007    4 

Et je veux groupe par EmployeeID et le montant du crédit. Le hic est que je dois le changement dans le montant du crédit entre la date max et min si:

EmployeeID   CreditAmount 
-----------   -------------- 
    5       10 
    6       1 

Comment puis-je faire cela?

+0

Veuillez éditer les données de sorte que 15 passe à 03/01 et 7 à 4/22. C'est déroutant pour le moment. – Quassnoi

+0

Les données doivent inclure les conditions aux limites: si le montant de 3/1 est de 15 et le montant de 4/22 est de 12, je devrais avoir un résultat de 7 au lieu de 10? – jcollum

Répondre

0

pour MS SQL, cela devrait le faire

SELECT 
    ep.employeeID, rc.creditAmount, 
    datediff(month, max(ep.punchdate), min(ep.punchdate)) 
FROM 
    EmployeePunch ep 
INNER JOIN 
    ResponderCredit rc ON rc.employeeID = ep.employeeID AND 
    rc.punchdate = rc.creditdate 
group by 
    EmployeeID, Credit 
ORDER BY 
    ep.employeeID 
+0

Je pense que le PO cherche réellement la différence entre le rc.creditAmount min et le rc.creditAmount max. –

+0

Oui, je suis d'accord. C'est presque certainement une faute de frappe de la part de l'OP. – Cerebrus

+0

Modifié la question –

1

Dans Oracle:

SELECT r1.employeeID, amMax - amMin 
FROM (
    SELECT employeeID, amMin 
    FROM (
     SELECT 
      ROW_NUMBER() OVER (PARTITION BY ep.EmployeeID ORDER BY rc.creditdate) AS rnMin, 
      ep.employeeID, rc.creditAmount AS amMin 
     FROM 
      EmployeePunch ep, ResponderCredit rc 
     WHERE 
      rc.employeeID = ep.employeeID 
      AND rc.punchdate = rc.creditdate 
     ) 
    WHERE rn_min = 1 
    ) r1, 
    (
    SELECT employeeID, amMin 
    FROM (
     SELECT 
      ROW_NUMBER() OVER (PARTITION BY ep.EmployeeID ORDER BY rc.creditdate DESC) AS rnMax, 
      ep.employeeID, rc.creditAmount AS amMax 
     FROM 
      EmployeePunch ep, ResponderCredit rc 
     WHERE 
      rc.employeeID = ep.employeeID 
      AND rc.punchdate = rc.creditdate 
     ) 
    WHERE rn_max = 1 
    ) r2 
WHERE r1.employeeID = r2.employeeID 
+0

Très bon usage de ROW_NUMBER. – casperOne

0

Voici une solution pour MSSQL.

Il affichera une valeur négative si le crédit a diminué pendant la période.

Il a un peu et jointures peut probablement être optimisé, mais probablement pas par beaucoup

 
SELECT maxCredit.employeeID, maxCredit.creditAmount - minCredit.creditAmount 
FROM 
(
SELECT 
    ep.employeeID, rc.creditAmount 
FROM 
  EmployeePunch ep 
INNER JOIN 
    ResponderCredit rc 
ON rc.employeeID = ep.employeeID AND rc.punchdate = rc.creditdate 
INNER JOIN 
    (
    SELECT ep2.employeeID, MAX(ep2.punchdate) AS maxCreditdate 
    FROM EmployeePunch ep2 GROUP BY ep2.employeeID 
    ) innermax 
ON innermax.employeeID = ep.employeeID AND ep.punchdate = innermax.maxcreditDate 
) maxCredit 
INNER JOIN 
(
SELECT 
    ep.employeeID, rc.creditAmount 
FROM 
  EmployeePunch ep 
INNER JOIN 
    ResponderCredit rc 
ON rc.employeeID = ep.employeeID AND rc.punchdate = rc.creditdate 
INNER JOIN 
    (
    SELECT ep3.employeeID, MIN(ep3.punchdate) AS minCreditdate 
    FROM EmployeePunch ep3 GROUP BY ep3.employeeID 
    ) innermin 
ON innermin.employeeID = ep.employeeID AND ep.punchdate = innermin.mincreditDate 
) minCredit 
ON maxCredit.employeeID = minCredit.employeeID 
+0

Vous avez oublié la date ... – Eppz

+0

Je l'ai fait juste selon le résultat requis – John

+0

Le résultat requis est déroutant que les montants de crédit min et max pour chaque employé sont également les dates min et max. Je l'ai bien cette fois-ci cependant. – John

0

C'est ce que vous cherchez, je crois ....

SELECT 
    ep.employeeID, Max(datediff(day, ep.punchdate, rc.creditDate)) As [# of Days], rc.creditAmount 
FROM 
    EmployeePunch ep 
INNER JOIN 
    ResponderCredit rc 
ON 
    rc.employeeID = ep.employeeID AND rc.punchdate = rc.creditdate 
group by ep.employeeID, rc.creditAmount 
ORDER BY ep.employeeID 

Will résultats de rendement:

EmployeeID # of Days CreditAmount  
5     0    5  
5     2    7  
5     111   15  
6     0    3  
6     334   4 
Questions connexes