2013-11-09 90 views
0

我需要編寫一個查詢,我需要檢查計數記錄,如果計數爲0,我想插入其他記錄更新記錄需要插入一個記錄,如果計數= 0,否則,更新記錄

如果我使用光標同樣的事情,它工作正常,但沒有光標

這裏同樣的事情,不工作是我的查詢(無光標)

---沒有光標

INSERT INTO [dbo].Products_Del (product_Id, product_Del_startdate)     
     SELECT f.product_Id, min(cast(product_startdate as datetime)) AS orig_order_date FROM [dbo].Products f 
      inner join [dbo].Products_Del ac on f.product_Id = ac.product_Id 
      WHERE Product_Status = 'ORDERED' 
      AND product_startdate != '.'  
      AND (select COUNT(*) FROM products f1 
      INNER JOIN dbo.Products_Del ac on f1.product_Id = ac.product_Id 
      where f1.product_Id = f.product_Id) = 0 
      GROUP BY f.product_Id --order by product_Id 



-- Update if exists 
     ;with cts 
     AS ( 
      SELECT product_Id , min(cast(product_startdate as datetime)) as orig_date from [dbo].Products f 
       WHERE product_Id in (select product_Id from Products_Del) 
       and Product_Status = 'ORDERED' 
       AND product_startdate != '.' -- ignore rows where date is unknown 
       AND (select COUNT(*) FROM Products f1 
       INNER JOIN dbo.Products_Del ac on f1.Product_id = ac.Product_id 
       where f1.product_Id = f.product_Id) = 1 
       GROUP BY product_Id 
      ) 
     UPDATE ac 
     SET ac.product_Del_startdate = cts.orig_date 
     FROM Products_Del ac 
     INNER JOIN cts ON ac.product_Id = cts.product_Id 

但是這樣的工作不錯(用光標)

DECLARE @v_count  INT 
    DECLARE @c_product_id INT 
    DECLARE @c_product_date DATETIME 


DECLARE cursor1 CURSOR FOR 
SELECT product_id, 
     min(cast(product_startdate as DATETIME)) AS orig_order_date 
FROM [dbo].Products 
WHERE Product_Status = 'ORDERED' 
AND product_startdate != '.' -- ignore rows where date is unknown 
GROUP BY product_id 
--order by product_id 

OPEN cursor1 
FETCH NEXT FROM cursor1 INTO @c_product_id,@c_product_date 
WHILE(@@FETCH_STATUS = 0) 
BEGIN 
    SELECT @v_count = COUNT(*) 
      FROM [dbo].Products_Del 
      WHERE product_Id = @c_product_id 
      IF @v_count = 1 
      BEGIN 
       -- If so, plug the date into that row. 
       UPDATE [dbo].Products_Del 
       SET product_Del_startdate = @c_product_date 
       WHERE product_Id = @c_product_id 
      END 
      ELSE 
      BEGIN 
       -- If not, then create a new row in the aircraft_delivery_status table 
       IF @v_count = 0 
       BEGIN 
        INSERT INTO [dbo].Products_Del 
         (product_Id, product_Del_startdate) 
        VALUES (@c_product_id, @c_product_date) 
       END 
      END 

    FETCH NEXT FROM cursor1 INTO @c_product_id,@c_product_date  

END 
CLOSE cursor1 
DEALLOCATE cursor1 

與模式SQL小提琴鏈接 http://sqlfiddle.com/#!6/a7d0d/1

+2

檢查出MERGE聲明。 –

回答

1

在INSERT語句中,你已經加入

inner join [dbo].Products_Del ac on f.product_Id = ac.product_Id 

不正確只是將其刪除

在更新聲明(或ctp)您有不正確的條件:

(select COUNT(*) FROM Products f1 
       INNER JOIN dbo.Products_Del ac on f1.Product_id = ac.Product_id 
       where f1.product_Id = f.product_Id) = 

,因爲你必須在產品表中的相同的product_id多行,你可以在這個子查詢

還可以有超過一排,我可以建議以下查詢:

WITH OrderedProducts as(
    SELECT p.product_id as product_id, 
     min(cast(product_startdate as datetime)) as start_date 
    FROM [dbo].[Products] as p 
    WHERE p.Product_Status = 'ORDERED' 
     AND p.Product_startdate != '.' 
    GROUP BY p.product_id 
) 
UPDATE pd 
SET pd.product_Del_startdate = op.start_date 
FROM Products_Del pd 
    INNER JOIN OrderedProducts as op ON pd.product_Id = op.product_Id 

;WITH OrderedProducts as(
    SELECT p.product_id as product_id, 
     min(cast(product_startdate as datetime)) as start_date 
    FROM [dbo].[Products] as p 
    WHERE p.Product_Status = 'ORDERED' 
     AND p.Product_startdate != '.' 
    GROUP BY p.product_id 
) 
INSERT INTO [dbo].Products_Del (product_Id, product_Del_startdate) 
    SELECT op.product_id, op.start_date FROM OrderedProducts as op 
    WHERE NOT EXISTS (
     SELECT pd.product_id FROM [dbo].Products_Del as pd 
     WHERE pd.product_id = op.product_id) 
+0

非常感謝。有用! – Gudiya

相關問題