查询从 3 个表中获取数据,主表和总和列从彼此 2 个表中获取

Posted

技术标签:

【中文标题】查询从 3 个表中获取数据,主表和总和列从彼此 2 个表中获取【英文标题】:Query to get data from 3 tables, main tables and sum column from each other 2 tables 【发布时间】:2021-02-28 04:25:12 【问题描述】:

我正在努力查询以从 3 个表中获取数据:

供应商:

supp_id     int
name        nvarchar(200)
phone       nvarchar(10)
location    nvarchar(50)
note        nvarchar(MAX)
date        date

供应商发票:

ID          int 
supp_id     int 
o_number    nvarchar(50)
price       decimal(18, 2)
note        nvarchar(MAX)
date        date
image       image

suppliers_payments:

ID        int
supp_id   int
value     decimal(18, 2)
method    nvarchar(30)
note      nvarchar(MAX)
date      date

我想要得到的是这些信息:

suppliers.supp_id,suppliers.name,suppliers.phone,(sum(suppliers_invoices.price),
(sum(suppliers_payments.value), ((sum(suppliers_invoices.price) - (sum(suppliers_payments.value))
group by suppliers.supp_id.

我想获取每个供应商发票的价格总和和支付的价值总和。

我现在得到的是错误的数据,因为我认为价格乘以其他表格的行数。

这是我尝试过的:

SELECT dbo.suppliers.supp_id, dbo.suppliers.name, dbo.suppliers.phone, 
SUM(dbo.suppliers_invoices.price) AS Expr1, SUM(dbo.suppliers_payments.value) AS Expr2
FROM dbo.suppliers INNER JOIN dbo.suppliers_invoices ON dbo.suppliers.supp_id = 
dbo.suppliers_invoices.supp_id INNER JOIN dbo.suppliers_payments ON dbo.suppliers.supp_id = 
dbo.suppliers_payments.supp_id GROUP BY dbo.suppliers.supp_id, dbo.suppliers.name,dbo.suppliers.phone

这是我正在测试的一些数据:

供应商:

supp_id   name    phone         location    note    date
1         test    0543642256    NULL        NULL    2020-11-17
2         test2   0543642211    NULL        NULL    2020-11-17

供应商发票:

ID  supp_id   o_number   price      note    date         image     
1   1         123        5000.00    NULL    2020-11-17   NULL
2   1         1235       3000.00    NULL    2020-11-17   NULL
3   2         55         2000.00    NULL    2020-11-17   NULL

suppliers_payments:

ID  supp_id   value     method    note   date   
1   1         2000.00   cash      NULL   2020-11-17
2   1         2000.00   visa      NULL   2020-11-17

我想得到的是:

supp_id   name    phone         price       value   remain
1         test    0543642256    8000        4000    4000
2         test2   0543642211    2000        0       2000      

谢谢。

【问题讨论】:

请提供一些DDL/DML形式的样本数据进行测试。 仅供参考,列的 3 部分命名到期 to be deprecated;给你的对象起别名并用它来限定你的列。对空格和换行符的一些良好使用也不会出错。 图像数据类型已被弃用 15 年 - 现在不要使用它! @DaleK 我更新了问题,请看一下 @SMor,谢谢你的建议,我应该改用什么?? 【参考方案1】:

我认为您错过了左连接而不是内连接。

请找到以下查询:

SELECT sup.name, sum(sup_inv.price), sum(sup_pay.value), sup.supp_id
FROM suppliers sup
left JOIN suppliers_invoices sup_inv
 ON sup.supp_id = sup_inv.supp_id 
left JOIN suppliers_payments sup_pay
ON sup.supp_id = sup_pay.supp_id 
group by sup.supp_id, sup.name;

【讨论】:

【参考方案2】:

您需要分别对价格和价值求和,然后与它们进行交互。不要在尝试做复杂的求和和预先加入时杀死自己;如果你加入错误,你会得到错误的计算。

SELECT 
  s.name,
  s.phone,
  inv.sumPrice,
  val.sumValue,
  isnull(inv.sumPrice, 0) - isnull(val.sumValue, 0) as sumProfit
FROM suppliers s
LEFT JOIN ( /* see this subquery, pretending to be a table */
           SELECT 
             supp_id,
             sum(price) as sumPrice
           FROM suppliers_invoices
           GROUP BY supp_id) inv on s.supp_id = inv.supp_id
LEFT JOIN ( /* see this subquery, pretending to be a table */
           SELECT 
             supp_id,
             sum([value]) as sumValue
           FROM suppliers_payments
           GROUP BY supp_id) val on s.supp_id = val.supp_id ;

Demo here

【讨论】:

感谢您的帮助,并解释了答案【参考方案3】:

您需要在子查询中预先聚合。一种选择使用横向连接:

select s.*, si.price, sp.value, si.price - sp.value as remain
from suppliers s
cross apply (
    select coalesce(sum(si.price), 0) as price
    from suppliers_invoices si
    where si.supp_id = s.supp_id
) si
cross apply (
    select coalesce(sum(sp.value), 0) as value
    from suppliers_payments sp
    where sp.supp_id = s.supp_id
) sp

【讨论】:

感谢您的快速回答。

以上是关于查询从 3 个表中获取数据,主表和总和列从彼此 2 个表中获取的主要内容,如果未能解决你的问题,请参考以下文章

从 2 个表中获取数据,其中一个表依赖于另一个表

3 个表和一个子查询的 SQL 连接问题

MySQL JOIN 2 个表并分别获取两个表的总和

如何编写从多个表中获取多行数量总和的查询?

将 5 个表数据合并到主表中

从 3 个表中获取数据时的 Db2 查询