【问题标题】:How to make these JOIN queries?如何进行这些 JOIN 查询?
【发布时间】:2010-01-01 19:17:49
【问题描述】:

我正在处理一些关于我的作业的问题,我们将不胜感激。

  1. 列出分支机构以及员工人数和分配给他们的客户、总贷款金额、总账户余额、位于给定城市的分支机构的资产。
  2. 列出在给定时间段内进行账户和贷款操作的客户
  3. 列出员工以及在给定时间段内每个客户服务的人数

我想一个简单的例子就足够我解决休息了。

这是我迄今为止尝试的第一个:

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

这是架构!

【问题讨论】:

  • 请展示你的尝试:)
  • 好的,这是我正在尝试的第一个 ALTER PROCEDURE [dbo].[SelecBranchesByCity] @City varchar(50) AS BEGIN select Br.Name as BranchName, COUNT(emps.ID)作为 NumberOfEmployee,SUM(emps.NumberOfCustomers) 作为 TotalCustomers,SUM(lo.Amount) 作为 TotalAmountOfLoan,SUM(acc.Balance) 作为 TotalBalance,Br.Assets 作为来自分支机构的资产 Br 左外连接员工 emps 上的 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
  • 不管怎样,Customers 应该在表中包含loanID,因为客户可以拥有多个贷款账户。此外,您的LoanCustomer 表中已经有CustomersLoans 之间的链接。
  • @Kubi:您应该使用此信息更新您的问题,不要将其发布在 cmets 中,因为人们很难阅读和/或编辑格式。
  • 虽然我知道我们中的一些人发出了有关架构的警告,但重做它然后更改您的问题并不是很好,这会使以前的答案无效并期望人们离开再次通过该过程。不仅如此,您的示例查询既不匹配新模式也不匹配旧模式。恕我直言,我很乐意帮助人们,但这不是一个提供一对一教程的网站;大多数人不会愿意花无限的时间来帮助你完成一项任务,尤其是当你的问题是三方的,而你只要求一个“简单的例子”时。

标签: sql-server join


【解决方案1】:

架构令人恐惧。多对多客户贷款?客户帐户上的多对多?为什么??员工有一个branchname 列,而不是与branches 的FK 关系。 loan_operationsemployees 有 FK!?我并不是要偏离主题或听起来轻率,但是这里有很多反模式,我什至不知道从哪里开始。但无论如何,我会尽力帮助解决具体问题。

第一季度:

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

我会注意到您在loansloan_operations 中都有一个amount 列。很难知道这两者之间有什么区别 - loans 完全有可能根本不应该有这个列,而是应该从 loan_operations 的列中求和。

第二季度:

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

第三季度:

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

【讨论】:

  • 嘿亚伦谢谢!是的,架构就是这样。但我也在编程一个接口,我不想处理那么多 FK :) 我想做最小的事情。 reqs :) 再次感谢一百万!
  • 顺便说一句,对于客户和贷款来说是多对多,因为任务需要这样:)
  • 好的,我第一个有问题!首先cmpe.emu.edu.tr/chefranov/Cmpe354-09Fall/Notes/… 这里是任务。从第一个查询开始,totalloanamount 和 totalaccountbalance 总是返回 0 ?
  • 您的问题是什么?为什么总显示为 0?可能是因为它 为零。您期望的是什么?您的数据是什么?
  • “客户贷款上的多对多?客户帐户上的多对多?为什么??” - 不是 OP 的答案,但我可以在现实生活中看到这一点。假设我和一个联署人签署了汽车贷款和个人贷款,现在我们对客户和贷款之间的多对多关系有了一个完全合理的解释。假设我和我丈夫有活期账户和一个储蓄账户,那么对于客户和账户之间的多对多关系有一个完全合理的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 2015-09-16
  • 2011-06-12
相关资源
最近更新 更多