【问题标题】:calculates between These two columns in SQL server [closed]在 SQL Server 中的这两列之间计算 [关闭]
【发布时间】:2017-05-11 01:39:26
【问题描述】:

我想在查询中添加一列在这两个列之间进行计算在同一个查询中...................... ......................................

  ,isnull(sum(ORDERS.Net_Amount) + 0,0) as orders
  ,isnull(sum (convert(float,(RECEIPTS.Amount))) + 0,0) as recepts

在 SQL 服务器中

SELECT CUSTOMERS.[ID_CUSTOMER]
      ,[FIRST_NAME]
      ,[TEL]
      ,[EMAIL]
      ,isnull(sum(ORDERS.Net_Amount) + 0,0) as orders
      ,isnull(sum (convert(float,(RECEIPTS.Amount))) + 0,0) as recepts
      ,[CRIDIT_LIMIT]
      ,[CUSTOMER_SINCE]
      ,[ADRESS]
      ,CUSTOMERS.[state]
  FROM [CUSTOMERS]
LEFT JOIN ORDERS on CUSTOMERS.ID_CUSTOMER = ORDERS.CUSTOMER_ID
LEFT JOIN RECEIPTS on CUSTOMERS.ID_CUSTOMER = RECEIPTS.ID_CUSTOMER
GROUP BY CUSTOMERS.[ID_CUSTOMER]
      ,[FIRST_NAME]
      ,[TEL]
      ,[EMAIL]
      ,[CRIDIT_LIMIT]
      ,[CUSTOMER_SINCE]
      ,[ADRESS]
      ,CUSTOMERS.[state]

CUSTOMERS 表

SELECT [ID_CUSTOMER]
      ,[FIRST_NAME]
      ,[TEL]
      ,[EMAIL]
      ,[IMAGE_CUSTOMER]
      ,[CRIDIT_LIMIT]
      ,[CUSTOMER_SINCE]
      ,[ADRESS]
      ,[Balance]
      ,[state]
  FROM [CUSTOMERS]

订单表

SELECT [ID_ORDER]
      ,[DATE_ORDER]
      ,[CUSTOMER_ID]
      ,[DESCRIPTION_ORDERS]
      ,[SALEMAN]
      ,[ORDER_TOTAL]
      ,[Discount_Of_Total]
      ,[Total_After_Discount]
      ,[Paid_Up]
      ,[Net_Amount]
      ,[state]
  FROM [ORDERS]

收据表

SELECT [image_state]
      ,[ID_RECEIPT]
      ,[ID_CUSTOMER]
      ,[Date]
      ,[Ref]
      ,[Amount]
      ,[Memo]
      ,[User_Name]
      ,[state]
      ,[Payment_Method]
      ,[Account_ID]
  FROM [RECEIPTS]

【问题讨论】:

  • 先上一个基本的SQL教程。然后回来为您的问题添加更多细节,例如示例数据和预期输出
  • Hive ua 您的代码以更正和您的 bd 架构
  • 我更新了我的问题
  • 请包含Customers 表。
  • 请为您正在使用的SQL的形式添加标签,例如MySQLSQL-Server

标签: sql sql-server database select


【解决方案1】:

订单和收据之间并没有真正的关联(收据并不指具体的订单),所以不要将两者结合起来。相反,您要做的是找到每个客户的订单金额和收据金额并显示出来。因此,聚合每个客户的两个表并将结果外连接到客户表。

 select
   c.id_customer,
   c.first_name,
   c.tel,
   c.email,
   coalesce(o.sum_net_amount, 0) as order_amount,
   coalesce(r.sum_amount, 0) as receipt_amount,
   c.cridit_limit,
   c.customer_since,
   c.adress,
   c.balance,
   c.state
 from customers c
 left join
 (
   select customer_id, sum(net_amount) as sum_net_amount
   from orders
   group by customer_id
 ) o on c.id_customer = o.customer_id
 left join
 (
   select id_customer, sum(amount) as sum_amount
   from receipts
   group by id_customer
 ) r on c.id_customer = r.id_customer;

我看到您已经更新了您的请求,现在还询问总和的差额。好吧,SQL 中的减法运算符 - 不足为奇 - 减号:

   coalesce(o.sum_net_amount, 0) - coalesce(r.sum_amount, 0) as diff

【讨论】:

  • 抱歉,我忘记为表命名(来自客户 c)。我已经更新了我的答案。
  • Msg 207,级别 16,状态 1,第 24 行无效的列名称“customer_id”。消息 207,级别 16,状态 1,第 22 行无效的列名称“customer_id”。消息 207,级别 16,状态 1,第 11 行无效的列名称“余额”。
  • 好的,在某些表格中是id_customer,而不是customer_id(您与名称不一致)。你怎么没能自己发现这个?至于balance我不知道。您在customers 中显示该名称的列。这些信息不正确吗?
  • 这是很好的代码,谢谢
【解决方案2】:

请尝试以下...

SELECT Customers.ID_Customer,
       first_name,
       tel,
       email,
       SUM( net_amount ) AS OrdersTotal,
       COALESCE( sumAmount, 0 ) AS PaymentsTotal,
       SUM( net_amount ) - COALESCE( sumAmount, 0 ) AS DifferenceInTotals,
       cridit_limit,
       customer_since,
       adress,
       balance,
       state
FROM Customers
INNER JOIN Orders ON Customers.ID_Customer = Orders.Customer_ID
LEFT JOIN ( SELECT ID_Customer,
                   SUM( amount ) AS sumAmount
            FROM Receipts
            GROUP BY ID_Customer
          ) AS sumAmountFinder ON Customers.ID_Customer = sumAmountFinder.ID_Customer
GROUP BY Customers.ID_Customer,
         first_name,
         tel,
         email,
         cridit_limit,
         customer_since,
         adress,
         balance,
         state;

此答案基于以下假设:每个Customer 至少有一个Order,但可能没有Receipts

此语句本质上是您提供的带有以下修改的语句...

我已将JOIN 更改为OrdersINNER JOIN,因为我假设每个Customer 将至少有一个OrderLEFT JOIN 仅在您希望保留左表中的所有记录时才需要,这些记录在右表中没有至少一条匹配记录,如ON 子句所定义。 (注意:如果您希望保留右表中没有左表匹配记录的所有记录,请使用RIGHT JOIN)。

我已经用一个子查询将JOIN 替换为Receipts 表,该子查询计算Receipts 表中每个Customeramount 字段的总数。 LEFT JOIN Customers 和此子查询的结果之间是必需的,因为并非所有 Customers 都会有 Receipt。在这种情况下,LEFT JOIN 会将连接数据集中子查询中的每个字段设置为 NULL

SUM() 函数只遇到NULL 值,它返回NULL,而不是0。对于Customer 没有Receipts 的记录,PaymentsTotal 将设置为0,我使用了COALESCE() 函数。此函数将返回它遇到的第一个非NULL 参数。在这里,我将其设置为在遇到一个时返回amount 的总数,在遇到amount 时返回0

我已从您的字段和表格名称中删除了所有方括号。仅当您使用了其他不允许的名称时才需要它们,例如带有空格的名称(使用[Full Name] 而不是Full Name)或SQL-Server 保留的名称(如果您决定调用PaymentsTotal@ 987654360@,那么您将不得不使用AS [Sum])。许多程序员认为给字段起这样的名称是不好的做法,即使 [] 可能是这样,但幸运的是你没有使用任何其他名称。

我已从您的 SUM() 计算中删除了表名。由于只有一个表有一个名为net_amount 的字段,因此它将是连接数据集中的唯一字段名称,您也可以在不指定源表名称的情况下引用它们。在Customers.ID_Customer 的情况下,仍然需要指定源表,因为连接的数据集将有多个名为ID_Customer 的字段。此外,在使用 JOIN's 创建连接数据集时,您需要指定源表名称。

我还冒昧地更改了您的大小写方案。几乎所有内容都使用恒定的大写字母,这对眼睛来说是单调的。对 SQL 术语、表名和字段名使用不同的大小写可以更容易地识别每种类型的语句部分,从而使调试代码更容易。

最后,相对而言,cridit 实际上拼写为 credit,adress 实际上拼写为 address。

如果您有任何问题或cmets,请随时发表评论。

【讨论】:

  • 我会在几分钟内相应地更新我的答案。
  • 可能。不过,我可能需要几个小时,因为我有约会。
  • 更新已发布。请把结果告诉我。我会在一两个小时后回来。
  • 错误已更正,新代码已发布。我现在正在研究新的解释。
  • 你确定这个查询给你正确的结果吗?假设您有两个金额为 100 和 200 的订单以及两个金额为 10 和 20 的收据。您加入并获得 100|10、100|20、200|10、200|20。你相加得到 600|60。你不想用 300|30 代替吗?
猜你喜欢
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 2015-04-22
  • 1970-01-01
相关资源
最近更新 更多