SQL Server:根据其他2列中的条件更新boolean列

时间:2019-02-07 01:09:16

标签: sql sql-server tsql

当我的PrimaryInvoiceFile只有一个InvoiceFileId时,我需要将列InvoiceId中的所有行都设置为1(true)。

但是,如果InvoiceId有多个InvoiceFileId,则我需要将所有PrimaryInvoiceFile行设置为0(假),除了最近添加的InvoiceFileId根据添加的日期。

例如,它应如下所示:

|CreatedDate|InvoiceId|InvoiceFileId|PrimaryInvoiceFile|
+-----------+---------+-------------+------------------+
|2019-01-16 | 1       | 1           | 1                |
|2019-01-17 | 2       | 2           | 1                |
|2019-01-18 | 3       | 3           | 0                |
|2019-01-19 | 3       | 4           | 0                |
|2019-01-20 | 3       | 5           | 1                |
|2019-01-21 | 4       | 6           | 1                |

我刚刚添加了PrimaryInvoiceFile列迁移,并将默认值设置为0。

任何对此的帮助将不胜感激!我一直在努力尝试获取更新语句来执行此更新。

3 个答案:

答案 0 :(得分:4)

在进行更新时,可以使用行号来获得所需的结果。另外,按降序排列,以便获取最新日期。

让我们创建一个将PrimaryInvoiceFile保留为null的表,然后再进行更新。

select '2019-01-16' as CreatedDate, 1 as invoiceID,         1 as Invoicefield, null 
as PrimaryInvoiceFile 
into #temp 
union all 
select '2019-01-17' as CreatedDate, 2 as invoiceID,         2 as Invoicefield, null 
as Primaryinvoicefile union all 
select '2019-01-18' as CreatedDate, 3 as invoiceID,         3 as Invoicefield, null 
as Primaryinvoicefile union all 
select '2019-01-19' as CreatedDate, 3 as invoiceID,         4 as Invoicefield, null 
as Primaryinvoicefile union all 
select '2019-01-20' as CreatedDate, 3 as invoiceID,         5 as Invoicefield, null 
 as Primaryinvoicefile union all 
 select '2019-01-21' as CreatedDate, 4 as invoiceID,         6 as Invoicefield, null 
 as Primaryinvoicefile

update t 
set Primaryinvoicefile = tst.Rownum 
from #temp t 
join  
(Select  invoiceID, Invoicefield,CreatedDate, 
case when ROW_NUMBER() over (partition by invoiceID order by createddate desc) = 1 
then 1 else 0 end as Rownum   from #temp) tst 
on  tst.CreatedDate = t.CreatedDate 
      and tst.invoiceID = t.invoiceID 
      and tst.Invoicefield =  t.Invoicefield 

Case statement would make sure that you are value as 1 for only the rows where you have 1 row for invoice ID or for the most recent data. 

select * from #temp 

输出:

 CreatedDate    invoiceID   Invoicefield    PrimaryInvoiceFile
 2019-01-16        1          1                    1
 2019-01-17        2          2                    1
 2019-01-18        3          3                    0
 2019-01-19        3          4                    0
 2019-01-20        3          5                    1
 2019-01-21        4          6                    1

答案 1 :(得分:2)

请尝试以下操作:

;WITH Data AS (
    SELECT t.CreatedDate,t.InvoiceId,t.InvoiceFieldId,t.PrimaryInvoiceFile
        ,COUNT(*)OVER(PARTITION BY t.InvoiceId) AS [cnt]
    FROM [YourTableName] t
)
UPDATE d SET d.PrimaryInvoiceFile = CASE WHEN d.cnt = 1 THEN 1 ELSE 0 END
FROM Data d
;

查询玩法:

DROP TABLE IF EXISTS #YourTableName;
CREATE TABLE #YourTableName(CreatedDate DATETIME2,InvoiceId INT, InvoiceFieldId INT,PrimaryInvoiceFile BIT);
INSERT INTO #YourTableName(CreatedDate,InvoiceId,InvoiceFieldId)VALUES
    ('2019-01-16',1,1),('2019-01-17',2,2),('2019-01-18',3,3),('2019-01-19',3,4),('2019-01-20',3,5),('2019-01-21',4,6)

;WITH Data AS (
    SELECT t.CreatedDate,t.InvoiceId,t.InvoiceFieldId,t.PrimaryInvoiceFile,COUNT(*)OVER(PARTITION BY t.InvoiceId) AS [cnt]
    FROM #YourTableName t
)
UPDATE d SET d.PrimaryInvoiceFile = CASE WHEN d.cnt = 1 THEN 1 ELSE 0 END
FROM Data d
;

SELECT t.CreatedDate,t.InvoiceId,t.InvoiceFieldId,t.PrimaryInvoiceFile
FROM #YourTableName t
;

DROP TABLE IF EXISTS #YourTableName;

答案 2 :(得分:0)

如果默认的PrimaryInvoiceFile设置为0,则需要更新InvoiceId分组的最大CreatedDate的PrimaryInvoiceFile。

UPDATE inv1 
SET inv1.PrimaryInvoiceFile = 1
FROM invoices inv1 JOIN 
    (SELECT max(CreatedDate) as maxDate, InvoiceId 
     FROM invoices 
     GROUP BY InvoiceId ) as inv2  
WHERE inv1.CreatedDate=inv2.maxDate and inv1.InvoiceId= inv2.InvoiceId 
相关问题