简体   繁体   English

SQL基于同一表中的值在同一行上返回不同的值

[英]SQL Return different values on the same row, based on a value thats in the same table

I'm having a very difficult time trying to get my result to display they i need them to display... here and example of what my query looks like and below will be the result i need... 我在尝试获取我的结果以显示他们需要它们来显示时遇到了非常困难的时间...这里和我的查询看起来像的示例,下面将是我需要的结果...
iv been at this for a long time trying case statements and joins but have had no luck, if anybody can help i would really appreciate it. iv一直在尝试案例陈述和加入,但没有运气,如果有人可以帮助的话,我将非常感激。

table name dbo.DTLPAYMENTS 

columns   
PTNO    
CD   
AMT   
DESCRIPTION

my query displays my result back to me like so...also there never an equal amount line for credits and debits. 我的查询像这样向我显示结果...也永远不会有相等数量的贷方和借方行。 so a person can have more debits(>0) than credits(<0) and vice versa.... 因此,一个人的借方(> 0)多于贷方(<0),反之亦然。...

PTNO       /  CD    / AMT   / DESCRIPTION    
10007558931 30073   688.82    PAYMENT-ME    
10007558931 30073   -704.44   PAYMENT-ME    
10007558931 30073   704.44    PAYMENT-ME    
10007558931 30073   -688.82   PAYMENT-ME    
10007558931 30073   -698.82   PAYMENT-ME

i need this the debit and credit in separate columns 我需要在单独的列中使用借方和贷方
if there any way possible i can have it result back to me like so... 如果有任何可能的话,我可以像这样...

PTNO /      CD /    AMT /   DESCRIPTION / CD /     AMT / DESCRIPTION    
10007558931 30073   688.82  PAYMENT-ME    30073   -688.82  PAYMENT-ME   
10007558931 30073   704.44  PAYMENT-ME    30073   -698.82  PAYMENT-ME   
10007558931                               30073   -704.44  PAYMENT-ME      

and thanks you if anyone can help me 如果有人能帮助我,谢谢你

First, use CTEs to separate Credits and Debits into separate data sets, then FULL JOIN them based on PTNO, CD, and inverse value (* -1) of AMT. 首先,使用CTE将贷方和借方分离为单独的数据集,然后根据PTNO,CD和AMT的反值(* -1)进行完全联接。

Edit: Since joining based on AMT is not a goal, I used BatchSeqID as a way to sort the data chronologically. 编辑:由于基于AMT的加入不是目标,因此我使用BatchSeqID作为按时间顺序对数据进行排序的方法。 Using a ROW_NUMBER() to order the two data sets, I then joined then on this value. 然后使用ROW_NUMBER()对两个数据集进行排序,然后在该值上加入。

;WITH
Credit AS
(   SELECT PTNO,CD,AMT,DESCRIPTION,
    ROW_NUMBER()OVER(PARTITION BY PTNO,CD ORDER BY BatchSeqID) AS Sort
    FROM dbo.DTLPAYMENTS
    WHERE AMT < 0 ),
Debit AS
(   SELECT PTNO,CD,AMT,DESCRIPTION,
    ROW_NUMBER()OVER(PARTITION BY PTNO,CD ORDER BY BatchSeqID) AS Sort
    FROM dbo.DTLPAYMENTS
    WHERE AMT > 0 )

SELECT  ISNULL(c.PTNO,d.PTNO) AS PTNO,
        ISNULL(c.CD,d.CD) AS CD,
        --Credit data
        c.AMT AS CRAMT,
        c.DESCRIPTION AS CRDESCRIPTION,
        --Debit data
        d.AMT AS DBTAMT,
        d.DESCRIPTION AS DBTDESCRIPTION
FROM Credit c
FULL JOIN Debit d 
    ON d.PTNO = c.PTNO
    AND d.CD = c.CD
    AND d.Sort= c.Sort

if you don't like Matt's solution and the risk of duplicated rows, you can have every transaction on a different row: 如果您不喜欢Matt的解决方案以及行重复的风险,则可以将每个事务放在不同的行上:

SELECT PTNO,
       CASE WHEN AMT < 0 THEN cd ELSE null END DBTCD,
       CASE WHEN AMT < 0 THEN amt ELSE null END AMTCD,
       CASE WHEN AMT < 0 THEN DESCRIPTION ELSE null END DBTDESCRIPTION,
       CASE WHEN AMT > 0 THEN cd ELSE null END CRCD,
       CASE WHEN AMT > 0 THEN amt ELSE null END CRAMT,
       CASE WHEN AMT > 0 THEN DESCRIPTION ELSE null END CRDESCRIPTION
FROM TABLE1
order by PTNO, AMT

Here you can see and play wiht the result. 在这里,您可以查看和播放结果。

 PTNO           DBTCD   AMTCD   DBTDESCRIPTION  CRCD    CRAMT   CRDESCRIPTION
 10007558931    30073   -704    PAYMENT-ME      (null)  (null)  (null)
 10007558931    30073   -699    PAYMENT-ME      (null)  (null)  (null)
 10007558931    30073   -689    PAYMENT-ME      (null)  (null)  (null)
 10007558931    (null)  (null)  (null)          30073   689     PAYMENT-ME
 10007558931    (null)  (null)  (null)          30073   704     PAYMENT-ME

Assuming you want to sort the output on the magnitude of the amt column, try: 假设您要根据amt列的大小对输出进行排序,请尝试:

select ptno,
       max(case sign(amt) when 1 then cd end) dr_cd,
       max(case sign(amt) when 1 then amt end) dr_amt,
       max(case sign(amt) when 1 then description end) dr_desc,
       max(case sign(amt) when -1 then cd end) cr_cd,
       max(case sign(amt) when -1 then amt end) cr_amt,
       max(case sign(amt) when -1 then description end) cr_desc
from (select d.*, 
             row_number() over (partition by ptno, cd, sign(amt) 
                                order by abs(amt)) rn
      from DTLPAYMENTS d) sq
group by ptno, cd, rn
order by ptno, cd, rn

SQLFiddle here . SQLFiddle 在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM