【问题标题】:Can this Full Outer Join query be simplified?这个完全外连接查询可以简化吗?
【发布时间】:2016-09-01 21:49:08
【问题描述】:

我有来自两个来源的账单数据。我想加入他们的行列,以便能够查看一组中有记录而另一组中没有的记录,反之亦然。这个查询符合我的要求,但我觉得它可以写得更优雅?我只需要一个字段用于帐号和账单日期(M 和 Y),然后为每个来源中的费用单独设置一个字段。

DECLARE @BillDate datetime ='2/1/2016'

SELECT  ACCT_NO     =   COALESCE(BPFACCT,CSTACCT)               ,
        BillDate    =   COALESCE(BPFBillDate,CSTBillDate)       ,
        BPFCharge                                               ,
        CSTCharge                                               ,
        Delta       =   ROUND(COALESCE(BPFBill.BPFCharge,0)-COALESCE(CSTBill.CSTCharge,0),2)  
FROM
(
    SELECT  
            BPFACCT     =   acct_no                             , 
            BPFBillDate =   cast(billdate as date)              , 
            BPFCharge   =   SUM(charge)  
    FROM 
            cisbill b
        JOIN 
            cisbilldetail bd ON b.billid=bd.billid
    WHERE   
            billdate>=@BillDate
        AND 
            billdate<DATEADD(MONTH, 1, @BillDate)
    GROUP BY 
            acct_no, billdate
) BPFBill
FULL OUTER JOIN 
(
    SELECT  CSTACCT     =   acct_no                 , 
            CSTBillDate =   cast(bill_date as date) ,               
            CSTCharge   =   SUM(new_charges) 
    FROM 
            cst_bill
    WHERE 
            bill_date>=@BillDate
        AND 
            bill_date<DATEADD(MONTH, 1, @BillDate)
    GROUP BY
            acct_no, bill_date

) CSTBill 
    ON      BPFBill.BPFACCT=CSTBill.CSTACCT 
        AND 
            BPFBill.BPFBillDate=CSTBill.CSTBillDate

感谢任何反馈!

【问题讨论】:

  • 您不应该在搜索条件中使用函数,SQL Server 不能为此使用索引。使用值为 20160201 的日期变量并比较 bill_date &gt;= @billmonth and bill_date &lt; dateadd(month, 1, @billmonth)
  • group by billdate 在这里真的适合你吗?
  • @JamesZ - 谢谢,更新了问题,其中一个日期有时间部分,这就是为什么我把它放在那里,现在投射到日期......@JamieD77 - 是的,它可能有两个cst_bill 中当月的记录
  • 我的问题更多的是关于外部查询中的 JOIN 和 COALESCE 语句,这是最好的方法吗?
  • @neuralgroove 您对示例代码进行了相当大的更改。您现在想按账单日期显示总数吗?

标签: sql sql-server tsql full-outer-join


【解决方案1】:

我觉得这会给你一个更准确的结果..

DECLARE @StartDate DATETIME = '2/1/2016',
        @EndDate DATETIME
SET     @EndDate = DATEADD(MONTH, 1, @BillDate)

SELECT  ACCT_NO,
        MM,
        YY,
        BPFCharge = SUM(BPFCharge),
        CSTCharge = SUM(CSTCharge)
FROM 
(
    SELECT  acct_no,
            MM = MONTH(billdate),
            YY = YEAR(billdate),
            BPFCharge = charge
            CSTCharge = 0.00
    FROM    cisbill b
            JOIN cisbilldetail bd ON b.billid = bd.billid
    WHERE   billdate >= @StartDate
            AND billdate < @EndDate
    UNION ALL
    SELECT  acct_no,
            MONTH(bill_date),
            YEAR(Bill_date),
            0.00,
            new_charges
    FROM    cst_bill
    WHERE   bill_date >= @StartDate
            AND bill_date < @EndDate
) t
GROUP BY ACCT_NO,
        MM,
        YY

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多