如何生成基于外部ID的ID,其价格为负值

时间:2018-01-08 20:47:56

标签: sql-server sql-server-2014

我有这个数据集

InvoiceID     CDamount   companyname
   1             2500       NASA
   1            -2500       NASA
   2             1600       Airjet
   3             5000       Boeing
   4            -600        EXEarth
   5             8000       SpaceX
   5            -8000       SpaceX

我希望能够如下所示:

External ID    CDamount   companyname
   1             2500       NASA
   1-C          -2500       NASA
   2             1600       Airjet
   3             5000       Boeing
   4            -600        EXEarth
   5             8000       SpaceX
   5-C          -8000       SpaceX

我不能在CDamount< 0那么InvoiceID +' - ' +' C' ELSE InvoiceID END AS"外部ID"因为其他一些公司的负数也不属于这一类。

我想知道如何判断IF InvoiceID是否重复且CDAmount是否为负,然后创建新的外部ID?

这可能吗?

您可以在下面创建示例数据

Create Table #Incident (
InvoiceID int,
CDamount int,
Companyname Nvarchar(255))


insert into #Incident Values (1,2500,'NASA')
insert into #Incident Values (1,-2500,'NASA')
insert into #Incident Values (2,1600,'Airjet')
insert into #Incident Values (3, 5000, 'Boeing')
insert into #Incident Values (4, -600, 'ExEarth')
insert into #Incident Values (5,8000,'SpaceX')
insert into #Incident Values (5, -8000, 'SpaceX')

这是我使用的,但正如我所提到的,因为ID号4具有负值,我得到" -C"因为我不想这样做。

Select CASE WHEN T1.CDamount < 0 
            THEN  CAST(T1.InvoiceID AS nvarchar (255)) + '-' + 'C' 
            ELSE CAST(T1.InvoiceID AS nvarchar (255)) 
        END AS ExternalID,
T1.Companyname 
from #Incident AS T1

2 个答案:

答案 0 :(得分:0)

所以我根据我的SQL知识得到了这个,这适用于我的情况。 不确定这是否是一种明智的方式,但对于那些正在努力应对这样的情景的人来说,这可能是一个良好的开端:

;With CTE1 AS (
SELECT Count(*) AS Duplicate, T1.InvoiceID 
From #Incident AS T1
Group by T1.InvoiceID
),
Main AS (
Select CASE WHEN  T1.CDamount < 0 AND T2.Duplicate > 1
            THEN  CAST(T1.InvoiceID AS nvarchar (255)) + '-' + 'C' 
            ELSE CAST(T1.InvoiceID AS nvarchar (255)) 
        END AS ExternalID,
        T1.InvoiceID AS count,
        T1.CDamount,
T1.Companyname 
from #Incident AS T1
Join CTE1 AS T2 ON T1.InvoiceID = T2.InvoiceID
)
SELECT * FROM Main 

答案 1 :(得分:0)

使用ROW_NUMBER()函数的不带CTE的替代解决方案。

SELECT
          CASE WHEN CDAmount < 0 AND RowID > 1
            THEN InvoiceID + '-C'
            ELSE InvoiceID
          END AS ExternalID
        , CDAmount
        , CompanyName
    FROM
        (
            SELECT
                      CAST(InvoiceID AS NVARCHAR(255)) AS InvoiceID
                    , CDAmount
                    , CompanyName
                    , ROW_NUMBER() OVER (PARTITION BY InvoiceID ORDER BY CompanyName) AS RowID
                FROM
                    #Incident
        ) AS SourceTable

技巧是使用ROW_NUMBER()函数生成一个序列,该序列在InvoiceID更改时重置。这是子查询及其结果。当CDAmount为负且RowID大于1时,请使用CASE语句。

SELECT
          CAST(InvoiceID AS NVARCHAR(255)) AS InvoiceID
        , CDAmount
        , CompanyName
        , ROW_NUMBER() OVER (PARTITION BY InvoiceID ORDER BY CompanyName) AS RowID
    FROM
        #Incident

子查询结果:

+-----------+----------+-------------+-------+
| InvoiceID | CDAmount | CompanyName | RowID |
+-----------+----------+-------------+-------+
|         1 |     2500 | NASA        |     1 |
|         1 |    -2500 | NASA        |     2 |
|         2 |     1600 | Airjet      |     1 |
|         3 |     5000 | Boeing      |     1 |
|         4 |     -600 | ExEarth     |     1 |
|         5 |     8000 | SpaceX      |     1 |
|         5 |    -8000 | SpaceX      |     2 |
+-----------+----------+-------------+-------+