2013-06-26 66 views
2

我有一些問題創建查詢與此表和代碼, 我知道「GROUP BY Branch.BranchName」原因獲取多個記錄,但是,如何避免這種情況,並做在單個查詢中。 什麼,我試圖讓是 包含BRANCHNAME表 - 總payedvalue--總notpayedvalue子查詢返回多個值1與組通過

SELECT 
    (
     SELECT SUM (DeptDesciption.DeptValue) 
     FROM dbo.SudentPayments 
      INNER JOIN dbo.Student ON dbo.SudentPayments.StudentId = dbo.Student.StudentId 
      INNER JOIN dbo.DeptDesciption ON SudentPayments.DeptDesciptionId = DeptDesciption.DeptDesciptionId 
      INNER JOIN dbo.Branch on dbo.Branch.BranchId = Student.BranchId 
     WHERE SudentPayments.IsDeptPayed = 0 
     GROUP BY Branch.BranchName 
    ) AS Payed, 
    (
     SELECT SUM (DeptDesciption.DeptValue) 
     FROM dbo.SudentPayments 
      INNER JOIN dbo.Student ON dbo.SudentPayments.StudentId = dbo.Student.StudentId 
      INNER JOIN dbo.DeptDesciption ON SudentPayments.DeptDesciptionId = DeptDesciption.DeptDesciptionId 
      INNER JOIN dbo.Branch on dbo.Branch.BranchId = Student.StudentId 
     WHERE SudentPayments.IsDeptPayed = 1 
     GROUP BY Branch.BranchName 
    ) AS Notpayed, 
    Branch.BranchName 
FROM dbo.SudentPayments 
    INNER JOIN dbo.Student ON dbo.SudentPayments.StudentId = dbo.Student.StudentId 
    INNER JOIN dbo.DeptDesciption ON SudentPayments.DeptDesciptionId = DeptDesciption.DeptDesciptionId 
    INNER JOIN dbo.Branch on dbo.Branch.BranchId = Student.StudentId 
+1

首先要做的就是停止使用相關的子查詢,因爲它們是性能豬!改用連接,派生表或CTE。這是一個需要打破的SQL反模式。 – HLGEM

回答

5

嘗試這一個 -

SELECT 
     b.BranchName 
    , Notpayed = SUM(CASE WHEN sp.IsDeptPayed = 1 THEN d.DeptValue END) 
    , Payed = SUM(CASE WHEN sp.IsDeptPayed = 0 THEN d.DeptValue END) 
FROM dbo.SudentPayments sp 
JOIN dbo.Student s ON sp.StudentId = s.StudentId 
JOIN dbo.DeptDesciption d ON sp.DeptDesciptionId = d.DeptDesciptionId 
JOIN dbo.Branch b on b.BranchId = s.StudentId 
GROUP BY ALL b.BranchName 

UPDATE:

SELECT 
     b.BranchName 
    , Notpayed = ISNULL(t.Notpayed, 0) 
    , Payed = ISNULL(t.Payed, 0) 
FROM dbo.Branch b 
LEFT JOIN (
    SELECT 
      s.StudentId 
      , Notpayed = SUM(CASE WHEN sp.IsDeptPayed = 1 THEN d.DeptValue END) 
      , Payed = SUM(CASE WHEN sp.IsDeptPayed = 0 THEN d.DeptValue END) 
    FROM dbo.SudentPayments sp 
    JOIN dbo.Student s ON sp.StudentId = s.StudentId 
    JOIN dbo.DeptDesciption d ON sp.DeptDesciptionId = d.DeptDesciptionId 
    GROUP BY s.StudentId 
) t on b.BranchId = s.StudentId 
+0

非常感謝喲。但是這個查詢只能重新錄製一條記錄。但是我有更多的一個分支名稱,除此之外它工作正常 – sakir

+0

nope,沒有任何變化,結果相同 – sakir

+0

請參閱更新後的答案。 – Devart

3

錯誤是相當自我解釋,在你的s ubquery你正在返回多個結果,這是不允許的。如果從邏輯上考慮是否有多行應顯示哪一行?

你有這個問題的原因是,即使你已經按branch.BracnName分組,你還沒有鏈接回你的外部查詢,所以你的子查詢返回所有分支的結果。你會需要這樣的東西:

SELECT 
    (
     SELECT SUM (dd.DeptValue) 
     FROM dbo.SudentPayments sp 
      INNER JOIN dbo.Student s ON dbo.sp.StudentId = s.StudentId 
      INNER JOIN dbo.DeptDesciption dd ON sp.DeptDesciptionId = dd.DeptDesciptionId 
     WHERE s.IsDeptPayed = 0 
     AND s.BranchID = Branch.BranchID -- LINK TO OUTER BRANCH TABLE 
    ) AS Payed 
FROM dbo.Branch 

然而整個查詢冷,無需相關子查詢如下,如果你能避免相關子查詢的話,通常是一個好主意被改寫。在某些DBMS中,優化器可以優化一些子查詢並將它們轉換爲連接,但是對於相關子查詢來說,最簡單的方法是要求子查詢對每一行執行一次,這會比使用連接執行更多的開銷

SELECT Branch.BranchName, 
     Payed = SUM(CASE WHEN SudentPayments.IsDeptPayed = 1 THEN DeptDesciption.DeptValue ELSE 0 END), 
     Notpayed = SUM(CASE WHEN SudentPayments.IsDeptPayed = 0 THEN DeptDesciption.DeptValue ELSE 0 END) 
FROM dbo.SudentPayments 
     INNER JOIN dbo.Student 
      ON dbo.SudentPayments.StudentId = dbo.Student.StudentId 
     INNER JOIN dbo.DeptDesciption 
      ON SudentPayments.DeptDesciptionId = DeptDesciption.DeptDesciptionId 
     INNER JOIN dbo.Branch 
      ON dbo.Branch.BranchId = Student.StudentId 
GROUP BY Branch.BranchName; 
+2

+1 - 爲了好的答案。 – Devart