2017-04-20 88 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行兩次。 –