2017-04-20 89 views
1

我正在尝试执行UPDATE或INSERT,但我不确定是否可以不使用循环。这里是这样的例子:SQL更新或通过比较日期插入

说,我有这个SQL下面我加入了两个表:tblCompany和tblOrders。

SELECT CompanyID, CompanyName, c.LastSaleDate, o.SalesOrderID, o.SalesPrice 
, DATEADD(m, -6, GETDATE()) AS DateLast6MonthFromToday 
FROM dbo.tblCompany c 
CROSS APPLY (
    SELECT TOP 1 SalesOrderID, SalesPrice 
    FROM dbo.tblOrders o 
    WHERE c.CompanyID = o.CompanyID 
    ORDER BY SalesOrderID DESC 
    ) AS a 
WHERE Type = 'End-User' 

示例结果:

CompanyID, SalesOrderID, SalesPrice, LastSalesDate, DateLast6MonthFromToday 
101  10001   50   2/01/2016 10/20/2016 
102  10002   80   12/01/2016 10/20/2016 
103  10003   80   5/01/2016 10/20/2016 

我所试图做的是比较LastSalesDate和DateLast6MonthFromToday。条件如下:

  • 如果LastSalesDate较小(早期),然后执行INSERT INTO tblOrders(CompanyID,列1,列2 ...)VALUES(CompanyIDFromQuery,Column1Value,Column2Value)
  • 否则,执行UPDATE tblOrders SET SalesPrice = 1111 WHERE的SalesOrderID = a.SalesOrderID

作为上述样品结果,查询将只更新的SalesOrderID 10001和10003和公司102,由于LastSaleDate NO插入件是更大,那么就执行更新SalesOrderID。

我知道这可能是可以做到的,如果我创建一个游标循环遍历每条记录,然后进行比较然后更新或插入,但我想知道是否有另一种方式执行此循环,因为我有大约20K记录。

很抱歉的混乱,

+1

您应该至少显示表格的模式并告诉我们它们是如何连接的。 –

+1

我不明白这里的问题。为什么你不能只执行插入和更新语句 – maSTAShuFu

+0

给你的样本表数据.. –

回答

1

我不知道你的表结构及数据类型。我也不知道 关于重复和加入这两个表之间的关系。 但我只是想表明它是如何工作的下一个例子:

use [your test db]; 
go 

create table dbo.tblCompany 
(
    companyid int, 
    companyname varchar(max), 
    lastsaledate datetime, 
    [type] varchar(max) 
); 

create table dbo.tblOrders 
(
    CompanyID int, 
    SalesOrderID int, 
    SalesPrice float 
); 


insert into dbo.tblCompany 
values 
    (1, 'Avito', '2016-01-01', 'End-User'), 
    (2, 'BMW', '2016-05-01', 'End-User'), 
    (3, 'PornHub', '2017-01-01', 'End-User') 

insert into dbo.tblOrders 
values 
    (1, 1, 500), 
    (1, 2, 700), 
    (1, 3, 900), 
    (2, 1, 500), 
    (2, 2, 700), 
    (2, 3, 900), 
    (3, 1, 500), 
    (3, 2, 700), 
    (3, 3, 900) 

declare @column_1_value int = 5; 
declare @column_2_value int = 777; 

with cte as (
    select 
     CompanyID, 
     SalesOrderID, 
     SalesPrice 
    from (
     select 
      CompanyID, 
      SalesOrderID, 
      SalesPrice, 
      row_number() over(partition by CompanyID order by SalesOrderId desc) as rn 
     from 
      dbo.tblOrders 
    ) t 
    where rn = 1 
) 

merge cte as target 
using (select * from dbo.tblCompany where [type] = 'End-User') as source 
    on target.companyid = source.companyid 
    and source.lastsaledate >= dateadd(month, -6, getdate()) 
when matched 
    then update set target.salesprice = 1111 
when not matched 
    then insert (
     CompanyID, 
     SalesOrderID, 
     SalesPrice 
    ) 
    values (
     source.CompanyId, 
     @column_1_value, 
     @column_2_value 
    ); 

select * from dbo.tblOrders 

如果你给我一个信息,那么我就可以好好准备目标和源表。

+0

非常感谢您的示例代码。它对我来说看起来很复杂,但我会试着让你知道。 – Milacay

+0

您的解决方案非常完美。我跟着你的样品,看到它的工作原理。然后将这个逻辑应用于我的情况,并且它工作得很好。没有示例代码,我无法弄清楚。再次感谢你。 – Milacay

+0

@Milacay在所有情况下请小心,因为在合并声明中不能更新1行两次。 –