2

我在使用这些表和代码创建查询时遇到了一些问题,我知道“GROUP BY Branch.BranchName”会导致获取多条记录,但是,如何避免这种情况并在单个查询中做到这一点。我想要得到的是一个包含 BranchName 的表——支付的总价值——未支付的总价值

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
4

2 回答 2

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

更新:

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
于 2013-06-26T15:30:52.663 回答
3

该错误是不言自明的,在您的子查询中您返回多个结果,这是不允许的。如果您从逻辑上考虑如果有多行应该显示哪一行?

您遇到此问题的原因是,即使您已分组,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;
于 2013-06-26T15:39:16.810 回答