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 Fiddle 链接与架构 http://sqlfiddle.com/#!6/a7d0d/1

4

1 回答 1

1

在插入语句中,您的连接不正确

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

1

因为您在 products 表中有多个具有相同 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 )
于 2013-11-09T15:36:21.483 回答