2017-09-19 3 views
-2

Meine Unterabfrage gibt mehr als einen Wert zurück und gibt einen Fehler aus.Unterabfrage hat mehr als 1 Wert zurückgegeben. Die Unterabfrage, die SUM enthält (dbo.SalarySettingsBreakup.Amount) AS AmountSSB

(SELECT dbo.employee.id, 
     dbo.employee.employeecode, 
     dbo.employee.firstname, 
     dbo.employee.departmentid, 
     dbo.salarysettings.monthlyoffered, 
     dbo.salarysettings.id  AS SalarySettingsID, 
     (SELECT Sum(amount) AS AmountVP 
     FROM voucherprocesses 
     WHERE vouchertypeid = 2 
       AND employee = dbo.employee.id 
       AND voucherdate BETWEEN '9/1/2017 12:00:00 AM' AND 
             '9/30/2017 12:00:00 AM' 
     GROUP BY employee)  AS SalaryAdvance, 
     (SELECT Sum(dbo.salarysettingsbreakup.amount) AS AmountSSB 
     FROM dbo.employee 
       LEFT JOIN dbo.salarysettings 
         ON dbo.employee.id = dbo.salarysettings.employee 
       LEFT JOIN dbo.salarysettingsbreakup 
         ON dbo.salarysettings.id = 
          dbo.salarysettingsbreakup.salarysetting 
     WHERE dbo.salarysettingsbreakup.paymenttype = 2 
       AND dbo.salarysettingsbreakup.isactive = 1 
     GROUP BY dbo.employee.id) AS TotalDeduction, 
     (SELECT CASE 
        WHEN employee.joiningdate BETWEEN 
         '9/1/2017 12:00:00 AM' AND '9/30/2017 12:00:00 AM' THEN( 
       (salarysettings.monthlyoffered/30) * (30 - 
       (Datepart(dd, joiningdate) - 1))) 
        ELSE 0 
       END)    AS PayToBank 
FROM dbo.employee 
     LEFT JOIN dbo.salarysettings 
       ON dbo.employee.id = dbo.salarysettings.employee 
WHERE dbo.salarysettings.isactive = 1) 

Antwort

0

Hoffnung arbeiten, versuchen Sie dies:

(SELECT e.id, 
     e.employeecode, 
     e.firstname, 
     e.departmentid, 
     dbo.salarysettings.monthlyoffered, 
     dbo.salarysettings.id  AS SalarySettingsID, 
     (SELECT Sum(amount) AS AmountVP 
     FROM voucherprocesses 
     WHERE vouchertypeid = 2 
       AND voucherprocesses.employee = e.id 
       AND voucherdate BETWEEN '9/1/2017 12:00:00 AM' AND 
             '9/30/2017 12:00:00 AM' 
     )  AS SalaryAdvance, 
     (SELECT Sum(dbo.salarysettingsbreakup.amount) AS AmountSSB 
     FROM dbo.employee e2 
       LEFT JOIN dbo.salarysettings 
         ON e2.id = dbo.salarysettings.employee 

       LEFT JOIN dbo.salarysettingsbreakup 
         ON dbo.salarysettings.id = 
          dbo.salarysettingsbreakup.salarysetting 
         AND dbo.salarysettingsbreakup.paymenttype = 2 
         AND dbo.salarysettingsbreakup.isactive = 1 
     WHERE e2.id = e.id 
     ) AS TotalDeduction, 
     (SELECT CASE 
        WHEN employee.joiningdate BETWEEN 
         '9/1/2017 12:00:00 AM' AND '9/30/2017 12:00:00 AM' THEN( 
       (salarysettings.monthlyoffered/30) * (30 - 
       (Datepart(dd, joiningdate) - 1))) 
        ELSE 0 
       END)    AS PayToBank 
FROM dbo.employee e 
     LEFT JOIN dbo.salarysettings 
       ON e.id = dbo.salarysettings.employee 
WHERE dbo.salarysettings.isactive = 1) 
0

Sie haben viel zu lernen. Sie müssen verstehen, wie Unterabfragen funktionieren, sowie Outer-Joins. Folgendes ist falsch wegen 2 Problemen.

(SELECT Sum(dbo.salarysettingsbreakup.amount) AS AmountSSB 
    FROM dbo.employee 
      LEFT JOIN dbo.salarysettings 
        ON dbo.employee.id = dbo.salarysettings.employee 
      LEFT JOIN dbo.salarysettingsbreakup 
        ON dbo.salarysettings.id = 
         dbo.salarysettingsbreakup.salarysetting 
    WHERE dbo.salarysettingsbreakup.paymenttype = 2 
      AND dbo.salarysettingsbreakup.isactive = 1 
    GROUP BY dbo.employee.id) AS TotalDeduction, 

Zuerst ist, dass Sie die Unterabfrage nicht richtig korreliert haben. Wie Rahmat gepostet (aber nicht erklärt), müssen Sie die Mitarbeiter-ID aus der äußeren Abfrage mit der Unterabfrage verknüpfen. Da Sie die Unterabfrage nicht korreliert haben, werden für jede Zeile in der äußeren Abfrage mehrere Zeilen erzeugt, was zu Ihrem Fehler führt.

Darüber hinaus verursacht Ihr mangelndes Verständnis über die Korrelation Komplexität und einen logischen Fehler (der bei korrekter Korrelation verdeckt wird). Sie müssen die Tabelle employee nicht in Ihre Unterabfrage aufnehmen. Da Sie es in der Hauptabfrage mit der Tabelle employee korrelieren, ist es redundant. Darüber hinaus müssen Sie in der Unterabfrage keine Gruppierung vornehmen, da in der äußeren Abfrage ein einzelner Skalarwert pro Zeile generiert werden soll. Und schließlich gibt es keinen Grund für die äußere Verbindung in der Unterabfrage. Entweder haben Sie übereinstimmende Zeilen in lohneinstellungen oder Sie nicht. Ein innerer und äußerer Join führt zum gleichen Ergebnis - NULL, wenn keine Übereinstimmungen vorhanden sind. Ich frage auch, ob Sie bei den Tabellen- und Spaltennamen überhaupt eine Summe bilden müssen. Sie sollten nach Erklärungen darüber suchen, wie Outer-Joins funktionieren und was passiert, wenn Sie Spalten in der where-Klausel aus der nicht gespeicherten Tabelle (z. B. lumbersettingsbreakup) referenzieren.

So eine bessere Unterabfrage ist:

(SELECT Sum(bkp.amount) 
FROM dbo.salarysettings as sset 
INNER JOIN dbo.salarysettingsbreakup as bkp 
    ON sset.id = bkp.salarysetting 
    AND bkp.paymenttype = 2 
    AND bkp.isactive = 1 
WHERE sset.employee = dbo.employee.id) as TotalDeduction, 

Beachten Sie die Aufnahme einiger Best Practices. Geben Sie Ihren Tabellen einen lesbaren Aliasnamen und verwenden Sie ihn für alle referenzierten Spalten. Ich verachte auch die Praxis der Verwendung eines Tabellennamens als Spaltenname - das führt zu der Verwirrung beim Lesen Ihrer Abfragen IMO.

Verwandte Themen