简体   繁体   English

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

[英]SQL Server : update boolean column based on conditions from 2 other columns

I need to set all rows to 1 (true) in column PrimaryInvoiceFile when my InvoiceFileId only has one InvoiceId . 我需要的所有行设置为1(真)在列PrimaryInvoiceFile当我InvoiceFileId只有一个InvoiceId

However, if InvoiceId has multiple has multiple InvoiceFileId , I need to set all of the PrimaryInvoiceFile rows to 0 (false) except for the most recent InvoiceFileId added based on the date added. 但是,如果InvoiceId具有多个InvoiceFileId ,则我需要将所有PrimaryInvoiceFile行设置为0(假),但基于添加日期添加的最新InvoiceFileId除外。

For example it should look like this: 例如,它应如下所示:

|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                |

I just added the PrimaryInvoiceFile column migration and set the default value to 0. 我刚刚添加了PrimaryInvoiceFile列迁移并将默认值设置为0。

Any help with this would be greatly appreciated! 任何帮助,将不胜感激! I have been racking my head with this trying to get my update statements to perform this update. 我一直在努力尝试获取更新语句来执行此更新。

You can make use of rownumber while doing your update to achieve your desired results. 您可以在进行更新时利用行号来获得所需的结果。 Also, order by descending so that you get the most recent date. 另外,按降序排列,以便获取最新日期。

Lets create a table keeping PrimaryInvoiceFile as null and then updating later. 让我们创建一个将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 

Output: 输出:

 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

Please try this: 请尝试以下方法:

;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
;

Query to play around: 查询播放:

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;

If the default PrimaryInvoiceFile is set to 0, you need to update the PrimaryInvoiceFile of the maximum CreatedDate grouped by InvoiceId. 如果默认的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 

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

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