如何进行这些JOIN查询?

时间:2010-01-01 19:17:50

标签: sql-server join

我正在为我的任务处理一些问题,我们将非常感谢任何帮助。

  1. 将分支机构与员工人数,分配给客户,贷款总额,总账户余额,居住在特定城市的分支机构的资产一起列出。
  2. 列出在指定时间段内进行帐户和贷款操作的客户
  3. 在给定时间段内列出员工及每位客户所服务的人数
  4. 我想一个简单的例子足以让我解决休息问题。

    这是我到目前为止尝试的第一个:

    ALTER PROCEDURE [dbo].[SelecBranchesByCity]
        (@City varchar(50))
    AS
        select
            Br.Name as BranchName,
            COUNT(emps.ID) as NumberOfEmployee,
            SUM(emps.NumberOfCustomers) as TotalCustomers,
            SUM(lo.Amount) as TotalAmountOfLoan,
            SUM(acc.Balance) as TotalBalance,
            Br.Assets as Assets
        from Branches Br
        left outer join Employees emps on emps.[BranchName] = Br.Name
        left outer join Loans lo on lo.[BranchName] = Br.Name
        left outer join Accounts acc on acc.[BranchName] = Br.Name
        where
            Br.[Address] like '%'+@City+'%'
        GROUP BY
            Br.ID,
            Br.Name,
            Br.Assets
    

    这是架构! alt text

1 个答案:

答案 0 :(得分:2)

架构令人恐惧。客户贷款多对多?客户账户上多对多?为什么??员工拥有branchname列,而不是与branches的FK关系。 loan_operations有FK到employees !?我不是故意偏离主题或声音轻率,但这里有很多反模式,我甚至不知道从哪里开始。但无论如何,我会尝试帮助解决具体问题。

Q1:

CREATE PROCEDURE GetBranchSummaryByCity
    @City varchar(50)
AS
SELECT
    b.id, b.address, b.name, b.assets,
    b2.EmployeeCount, b2.CustomerCount,
    b2.TotalLoanAmount, b2.TotalAccountBalance
FROM branches b
INNER JOIN
(
    SELECT
        b.id,
        ISNULL(COUNT(DISTINCT e.id), 0) AS EmployeeCount,
        ISNULL(COUNT(c.id), 0) AS CustomerCount,
        ISNULL(SUM(l.amount), 0) AS TotalLoanAmount,
        ISNULL(SUM(a.balance), 0) AS TotalAccountBalance
    FROM branches b
    LEFT JOIN employees e
        -- Fix your schema so this matches the branch ID instead!
        ON e.branchname = b.name
    LEFT JOIN employee_customer ec
        ON ec.employeeid = e.id
    LEFT JOIN customers c
        ON c.id = ec.customerid
    LEFT JOIN customer_accounts ca
        ON ca.customerid = c.id
    LEFT JOIN accounts a
        ON a.id = ca.accountid
    LEFT JOIN loan_customer lc
        ON lc.customerid = c.id
    LEFT JOIN loans l
        ON l.id = lc.loanid
    WHERE b.Name LIKE '%' + @City + '%'
    GROUP BY b.id
) b2
ON b2.id = b.id

我会注意到amountloans都有loan_operations列。很难知道这两者之间有什么区别 - loans根本不应该有这个列,而应该从loan_operations中的列中总结出来。

Q2:

CREATE PROCEDURE FindCustomersWithLoansByDateRange
    @BeginDate datetime,
    @EndDate datetime
AS
SELECT c2.id, c2.name, c2.address, ...
FROM
(
    SELECT DISTINCT c.id
    FROM customers c
    INNER JOIN loan_customer lc
        ON lc.customerid = c.id
    INNER JOIN loans l
        ON l.id = lc.loanid
    INNER JOIN loan_operations lo
        ON lo.loanid = l.id
    WHERE lo.date BETWEEN @BeginDate AND @EndDate
) c1
INNER JOIN customers c2
ON c2.id = c1.id

Q3:

CREATE PROCEDURE GetEmployeeServiceSummaryByDateRange
    @BeginDate datetime,
    @EndDate datetime
AS
SELECT e.id, ISNULL(es.CustomerCount, 0) AS CustomerCount, e.name, e.position, ...
FROM employees e
LEFT JOIN
(
    SELECT e.id, COUNT(DISTINCT c.id) AS CustomerCount
    FROM employees e
    INNER JOIN employee_customer ec
        ON ec.employeeid = e.id
    INNER JOIN customers c
        ON c.id = ec.customerid
    INNER JOIN loan_customer lc
        ON lc.customerid = c.id
    INNER JOIN loans l
        ON l.id = lc.loanid
    INNER JOIN loan_operations lo
        ON lo.loanid = l.id
    WHERE lo.date BETWEEN @BeginDate AND @EndDate
    GROUP BY e.id
) es
ON es.id = e.id