SQL组连接表

时间:2013-12-19 02:37:51

标签: sql sql-server

您好我想以下面的格式显示记录。如何显示如下格式?

Branch   Total Payment Total Discount Total Net Payment
A          10,000         2,000          8,000
B          29,190         1,540          27,656

以下是我对上述内容的查询。请帮我。感谢。

SELECT  TranID, ProjCode,
CASE WHEN IsActive='N' THEN 'Cancellation' ELSE PaymentType END As PaymentType, 
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale_Before_CutOff END) END As Sale_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal, 
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff, 
CASE WHEN IsActive='N' THEN Net ELSE 0 END As Cancellation, 
CASE WHEN IsActive='N' THEN Net_Before_CutOff ELSE 0 END As Cancellation_Before_CutOff, 
CASE WHEN IsActive='N' THEN 0 ELSE Discount END As Discount, 
CASE WHEN IsActive='N' THEN 0 ELSE Discount_Before_CutOff END As Discount_Before_CutOff, AdditionalCommission,AdditionalCommission_Before_CutOff, Remark, UserStamp, BusinessDay, 
TranDate, BranchID, StaffCode, IsActive,Quantity
FROM            
(SELECT c.INTERNAL_TRAN_NUM AS TranID, c.PROJECT_CODE AS ProjCode, c.PAYMENT_TYPE AS PaymentType,d.QUANTITY As Quantity, 
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale, 
CASE WHEN DATEPART(hh, c.TRAN_DATE)<= DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale_Before_CutOff, 
CASE WHEN DATEPART(hh, c.TRAN_DATE)> DATEPART(hh, f.CUT_OFF_TIME) THEN c.NET_PAYMENT ELSE 0 END AS Net, 
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh,f.CUT_OFF_TIME) THEN c.NET_PAYMENT ELSE 0 END AS Net_Before_CutOff, 
CASE WHEN DATEPART(hh, c.TRAN_DATE) > DATEPART(hh,f.CUT_OFF_TIME) THEN c.DISCOUNT_AMOUNT ELSE 0 END AS Discount, 
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh,f.CUT_OFF_TIME) THEN c.DISCOUNT_AMOUNT ELSE 0 END AS Discount_Before_CutOff,
CASE WHEN DATEPART(hh, c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN d.USER_DEF8 ELSE 0 END As AdditionalCommission, 
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh, f.CUT_OFF_TIME) THEN d.USER_DEF8 ELSE 0 END As AdditionalCommission_Before_CutOff, 
c.REMARKS AS Remark, c.USER_STAMP AS UserStamp,CAST(DATEADD(hh, - DATEPART(hh, f.CUT_OFF_TIME), c.TRAN_DATE) AS DATE) AS BusinessDay, 
c.TRAN_DATE AS TranDate, e.BRANCH_ID AS BranchID, d.STAFF_CODE AS StaffCode, c.ISACTIVE AS IsActive
FROM SC_TRAN_HEADER AS c 
INNER JOIN SC_TRAN_DETAIL AS d ON d.INTERNAL_TRAN_NUM = c.INTERNAL_TRAN_NUM 
INNER JOIN SC_BRANCH AS e ON c.BRANCH_NUM = e.INTERNAL_NUM 
INNER JOIN SC_COMMISSION AS f ON f.BRANCH_NUM = c.BRANCH_NUM) AS TMP

2 个答案:

答案 0 :(得分:1)

根据您提问中的信息,我能提出的最好的是:

with cte as (<your query here>)
select branchid, sum(sale) as payment, sum(discount) as discount,
       sum(sale) - sum(discount)
from cte
group by branchid;

如果这不正确,请修改您的问题以提供更多信息以帮助您解决问题。

答案 1 :(得分:0)

首先,我会尝试从所有情况/条件中简化此查询的可读性。首先,您在初步查询中进行重复测试以获得截止期之前和之后的情况,然后根据撤回或非撤消进行其他操作,并再次针对“活动与非活动”进行操作。

简单的数学乘数......考虑您的查询段...您的内部查询以获取Sale和Sale_Before_CutOff的值。

CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale, 
CASE WHEN DATEPART(hh, c.TRAN_DATE)<= DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale_Before_CutOff, 

两者都测试截止时间的日期部分,答案可以是之前或之后,而不是两者。您对Net,Net_Before_Cutoff,Withdrawal,Withdrawal_Before_Cutoff执行相同的测试。

CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal, 
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff, 

然后,在查询的主要部分,您再次应用嵌套案例/何时(案例/何时)

CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale_Before_CutOff END) END As Sale_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal, 
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff, 

我要做的是,从您的子查询符合条件的记录中,我会得到原始数量列和6个标记作为多重符号。

SELECT ...
      c.TOTAL_PAYMENT,
      c.Net_Payment,
      c.Discount_Amount,
      CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) 
         THEN 1 ELSE 0 END as AfterMult,
      CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) 
         THEN 0 ELSE 1 END as BeforeMult,
      CASE WHEN c.PaymentType='Withdrawal' 
         THEN 1 ELSE 0 END as WithdrawalMult,
      CASE WHEN c.PaymentType='Withdrawal' 
         THEN 0 ELSE 1 END as NotAWithdrawalMult,
      CASE WHEN c.IsActive='N'
         THEN 1 ELSE 0 END As NotActiveMult,
      CASE WHEN c.IsActive='N'
         THEN 0 ELSE 1 END As ActiveMult, ...

注意,相同的条件适用于两个部分,只有THEN / ELSE将乘数从1到0分别交换到应该表示的值。因此,对于任何给定的记录,示例结果将是

Total_Payment   Net_Payment   Discount_Amount   AfterMult  BeforeMult  WithdrawalMult  NotAWithdrawalMult  NotActiveMult  ActiveMult
  100           86            14                1          0           1               0                   0              1
  200           170           30                0          1           0               1                   1              0

现在,简单的想法......如果你想知道在截止日期之前支付的总金额是多少并且不是撤回,在你的上层查询中它将是

Total_Payment * BeforeMult * NotAWithdrawal = TotalPayments_BeforeCutoff

与截止后付款

Total_Payment * AfterMult * NotAWithdrawal = TotalPayments_BeforeCutoff

您的活动与非活动的类似考虑。使用该乘数,当您在拉动记录时确定其状态时,在执行嵌套情况时没有任何意义。让我们来看看你的“销售”专栏...获取记录的内部查询是使用“Total_Payment”字段

CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale,

然后在上面是一个嵌套的情况/何时。

CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,

你关心销售金额的唯一时间是在截止日期之后,不是退出,当它处于活动状态时,所以只需乘以那些标志

Total_Payment * AfterMult * NotAWithdrawalMult * ActiveMult as Sale
Total_Payment * BeforeMult * NotAWithdrawalMult * ActiveMult as Sale_Before_Cutoff

最后,表中有很多其他列被拉动而未被使用,为什么要保留它们。而对于你想要获得SUM()的东西,它会更容易阅读它像

SUM( Total_Payment * AfterMult * NotAWithdrawalMult * ActiveMult ) as TotalSale
SUM( Total_Payment * BeforeMult * NotAWithdrawalMult * ActiveMult ) as TotalSale_Before_Cutoff

所有这一切,我告诉你这个...请确认背景,但是从上面应该有意义。另外,请注意,我添加的最后一个栏目是您可能正在寻找的最终总数,其中总和不关心时间截止之前或之后...只是事实它是有效的支付/折扣/净,是积极的,其中两个不是退出......看到这个,你需要确认它的准确性。前6个总结显示基于相应的截止后(无列名后缀)与截止之前(列名称为后缀)

SELECT
      PQ.Branch_Name,   <-- CONFIRM COLUMN FROM PreQuery (PQ alias)
      SUM( PQ.Total_Payment * PQ.AfterMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSale,
      SUM( PQ.Total_Payment * PQ.BeforeMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSale_BeforeCutoff,
      SUM( PQ.Discount_Amount * PQ.AfterMult * PQ.ActiveMult ) as TotalDiscount,
      SUM( PQ.Discount_Amount * PQ.BeforeMult * PQ.ActiveMult ) as TotalDiscount_BeforeCutoff,
      SUM( PQ.Net_Payment * PQ.AfterMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as Net,
      SUM( PQ.Net_Payment * PQ.BeforeMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as Net_BeforeCutoff,
      SUM( PQ.Total_Payment * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSaleAll,
      SUM( PQ.Discount_Amount * PQ.ActiveMult ) as TotalDiscountAll,
      SUM( PQ.Net_Payment * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as NetAll
   from
      ( select
              e.Branch_Name,   <-- GUESSING ON THIS COLUMN FOR ACTUAL BRANCH
              c.Total_Payment,
              c.Net_Payment,
              c.Discount_Amount,
              CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) 
                 THEN 1 ELSE 0 END as AfterMult,
              CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) 
                 THEN 0 ELSE 1 END as BeforeMult,
              CASE WHEN c.PaymentType='Withdrawal' 
                 THEN 1 ELSE 0 END as WithdrawalMult,
              CASE WHEN c.PaymentType='Withdrawal' 
                 THEN 0 ELSE 1 END as NotAWithdrawalMult,
              CASE WHEN c.IsActive='N'
                 THEN 1 ELSE 0 END As NotActiveMult,
              CASE WHEN c.IsActive='N'
                 THEN 0 ELSE 1 END As ActiveMult
           FROM 
              SC_TRAN_HEADER AS c 
                 INNER JOIN SC_TRAN_DETAIL AS d 
                    ON c.INTERNAL_TRAN_NUM = d.INTERNAL_TRAN_NUM
                 INNER JOIN SC_BRANCH AS e 
                    ON c.BRANCH_NUM = e.INTERNAL_NUM 
                 INNER JOIN SC_COMMISSION AS f 
                    ON c.BRANCH_NUM = f.BRANCH_NUM ) AS PQ
   group by
      PQ.Branch_Name    <--  AGAIN, confirm column name here