我需要编写一个查询,我需要检查计数记录,如果count为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
答案 0 :(得分: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 )