【问题标题】:SQL Server: Using Distinct Keyword in SQL Server Query fetches incorrect dataSQL Server:在 SQL Server 查询中使用 Distinct 关键字获取不正确的数据
【发布时间】:2011-02-20 10:35:31
【问题描述】:

我有一个包含以下列的表格。

ID   Amount
1      300
2      400
3      500
1      300 
2      400
3      500

对应于IDs有amount列。

我希望对使用 distinct 关键字的金额列求和,这样总和是 1200 而不是 2400。

但这里有问题;

如果ID是就说

ID   Amount
1      300
2      400
3      500
4      400 

值是 300、400、500 和 400。因此总数应该是 1600,但是因为我对 case1 使用了 DISTINCT 关键字,所以总数为 1200。

我应该如何编写我的 sql 查询以使两种情况都满足?

仅供参考,我的 SQL 查询不仅仅是求和,还涉及与其他表的关系,然后使用一些公式,我提出了数据。

谢谢

更新:添加 SQL 查询

Select distinct
  (
    (
      select sum( fees)
      from (
        select distinct billdetail.fees
        from billdetail
          join payment on billdetail.billdetailid = payment.billdetailid
        where billdetail.patientid=@patientid
      ) as temp
    )
    -
    (
      Select SUM (Payment.PlanPaid)
           + SUM (Payment.PatPaid)
           + SUM (Payment.WriteOff1)
           + SUM (Payment.WriteOff2)
      from  BillDetail
        left outer join Payment on BillDetail.BillDetailID = Payment.BillDetailID
      where BillDetail.PatientID = @patientid
    )
  )
from BillDetail
where PatientID = @patientid

【问题讨论】:

  • 发布您的 TSQL 查询......
  • 在 SO 评论框中发布时查询丢失格式...
  • 查询很疯狂!它生成与 BillDetail 记录一样多 (X) 行的摘要(内部和外部查询之间没有相关性),然后使用 DISTINCT 将 X 行相同的总和折叠成单个值。闻起来像一个非常非常低效的查询。对于当前查询,我更新的答案应该使用 (1/X) 的时间给出相同的结果。

标签: sql sql-server database sql-server-2005 sql-server-2008


【解决方案1】:

使用您的初始示例,如果在选择不同的行时提供具有相应 ID 的金额值,则可以正确计算总和。这样,您将选择总和相同但不完全重复的行。

SELECT SUM(Amount)
FROM (
  SELECT DISTINCT
    ID,
    Amount
  FROM YourTable
) s

在添加的查询中我认为你需要修改这个子选择:

select distinct billdetail.fees
from billdetail
  join payment on billdetail.billdetailid = payment.billdetailid
where billdetail.patientid=@patientid

像这样:

select distinct billdetail.ID, billdetail.fees
from billdetail
  join payment on billdetail.billdetailid = payment.billdetailid
where billdetail.patientid=@patientid

也就是说,通过添加billdetail.ID,您提供了必要的区分级别,因此得到的总和应该是正确的。

【讨论】:

    【解决方案2】:

    试试这个(未经测试,但请注意“SUM(DISTINCT ...)”)

    SELECT SUM(DISTINCT  billdetail.fees) - SUM (Payment.PlanPaid) + SUM (Payment.PatPaid) + SUM (Payment.WriteOff1) + SUM (Payment.WriteOff2)
    FROM  BillDetail
    LEFT OUTER JOIN Payment
    ON BillDetail.BillDetailID = Payment.BillDetailID
    WHERE BillDetail.PatientID = @patientid ;
    

    【讨论】:

    • 我已经尝试过了,但它不起作用。当有重复费用时它会失败,因为它会忽略重复的条目..)
    • @Romil,您的原始查询似乎也消除了重复费用(选择不同的 billdetail.fees)。请您发布一些示例数据以更清楚地解释您想要的结果。
    【解决方案3】:

    请尝试正确格式化查询以便于理解。

    Select distinct ((
        select sum( fees) 
        from (
                select distinct  billdetail.fees 
                from billdetail 
                join payment on billdetail.billdetailid = payment.billdetailid 
                where billdetail.patientid=@patientid) 
            as temp)
           -
        (Select SUM (Payment.PlanPaid) + SUM (Payment.PatPaid) + SUM (Payment.WriteOff1) + SUM (Payment.WriteOff2) 
        from  BillDetail 
        left outer join Payment on BillDetail.BillDetailID = Payment.BillDetailID 
        where BillDetail.PatientID = @patientid)
    ) 
    from BillDetail
    where PatientID = @patientid
    

    我将假设您只是想从 billdetail 与付款记录总和中区分费用。在第一部分中使用 [inner] JOIN 来表示费用,而在 LEFT 中用于付款(当右侧是值的来源时),这很奇怪。

    Select sum(f) from
    (
    Select
            fees
           -
            isnull((Select isnull(SUM (Payment.PlanPaid),0) +
                    isnull(SUM (Payment.PatPaid),0) + 
                    isnull(SUM (Payment.WriteOff1),0) +
                    isnull(SUM (Payment.WriteOff2),0)
            from  Payment 
            where BillDetail.BillDetailID = Payment.BillDetailID),0) f
    from BillDetail
    where PatientID = @patientid
    ) X
    

    【讨论】:

    • 我会记住您的第一个建议。我在 SQL Server 中发布了您的查询,它引发了“无法对包含聚合或子查询的表达式执行聚合函数”的错误。
    • @Romil - 它似乎需要另一个子查询 - 所以我已经更新了答案
    猜你喜欢
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2022-11-16
    • 2016-02-15
    相关资源
    最近更新 更多