Sql 使用Distinct违反主键约束
我对以下代码中的Sql 使用Distinct违反主键约束,sql,sql-server,sql-server-2008,tsql,primary-key,Sql,Sql Server,Sql Server 2008,Tsql,Primary Key,我对以下代码中的批量插入有问题: CREATE TABLE [dbo].[SubscribersDeliveries] ( [Status] [tinyint] NOT NULL, [LimitReached] [bit] NOT NULL, [IdSubscriber] [int] NOT NULL, [ContentType] [smallint] NOT NULL, [UTCDate] [date] NOT NULL, CONSTRAINT
批量插入有问题:
CREATE TABLE [dbo].[SubscribersDeliveries]
(
[Status] [tinyint] NOT NULL,
[LimitReached] [bit] NOT NULL,
[IdSubscriber] [int] NOT NULL,
[ContentType] [smallint] NOT NULL,
[UTCDate] [date] NOT NULL,
CONSTRAINT [PK_SubscribersDeliveries] PRIMARY KEY CLUSTERED
([Status] ASC, [LimitReached] ASC, [IdSubscriber] ASC)
) ON [PRIMARY]
INSERT INTO dbo.SubscribersDeliveries
(IdSubscriber,
Status,
LimitReached,
ContentType,
UTCDate)
SELECT DISTINCT s.IdSubscriber,
CASE cdoi.Status
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 1
WHEN 8 THEN 2
END AS Status,
CASE
WHEN CONDITION1 THEN 1
WHEN CONDITION2 THEN 1
WHEN CONDITION3 THEN 1
ELSE 0
END LimitReached,
cam.ContentType,
@Date
FROM Tables join
注意,我使用的是DISTINCT
子句。此脚本返回以下错误:
违反主键约束“PK_SubscriberDeliveries”。不能
在对象“dbo.subscribers”中插入重复键
有人能帮我吗
编辑:
当尝试按内部分组时,抛出一个错误,因为还需要按cdoi.IdDeliveryStatus分组,并且我需要按案例结果分组
CASE cdoi.IdDeliveryStatus
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 1
WHEN 8 THEN 2
END AS IdDeliveryStatus
现在我尝试封装所有查询
SELECT result.IdSubscriber,
result.IdDeliveryStatus,
result.LimitReached,
result.ContentType,
@Date
FROM (SELECT distinct s.IdSubscriber,
CASE cdoi.IdDeliveryStatus
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 1
WHEN 8 THEN 2
END AS IdDeliveryStatus,
CASE
WHEN cdoi.IdDeliveryStatus = 0
AND u.Limit1 > 0
AND ( ISNULL(s.Limit1, 0) + 1 >= u.Limit1) THEN 1
WHEN cdoi.IdDeliveryStatus IN ( 1, 3, 4, 5,
6, 7 )
AND ( ISNULL(s.Limit1, 0) + 1 >= u.Limit1) THEN 1
WHEN cdoi.IdDeliveryStatus IN ( 2, 8 )
AND ( ISNULL(s.Limit2, 0) + 1 >= u.Limit2) THEN 1
ELSE 0
END LimitReached,
cam.ContentType ContentType
FROM @tempCampaigns t
JOIN Campaign cam WITH (NOLOCK)
ON t.idcampaign = cam.IdCampaign
JOIN DBO.Subscriber s WITH (NOLOCK)
ON s.IdUser = cam.IdUser
JOIN DBO.[User] u WITH (NOLOCK)
ON s.idUser = u.idUser
JOIN DBO.Deliveries cdoi WITH (NOLOCK)
ON cdoi.IdSubscriber = s.IdSubscriber
AND cam.IdCampaign = cdoi.IdCampaign
WHERE s.IdSubscribersStatus < 3
) result
GROUP BY result.IdSubscriber,
result.IdDeliveryStatus,
result.LimitReached,
result.ContentType,
result.IdSubscribersStatus
SELECT result.IdSubscriber,
result.IdDeliveryStatus,
结果:,
result.ContentType,
@日期
从(选择不同的s.IdSubscriber,
案例cdoi.IdDeliveryStatus
当0时,则为0
当1时,则1
当2时,则2
3时1
4时1
5时1分
6时1分
7时1分
8时2分
以IdDeliveryStatus结束,
案例
当cdoi.IdDeliveryStatus=0时
而u.Limit1>0
和(ISNULL(s.Limit1,0)+1>=u.Limit1)然后是1
当cdoi.IdDeliveryStatus处于(1,3,4,5,
6, 7 )
和(ISNULL(s.Limit1,0)+1>=u.Limit1)然后是1
当cdoi.IdDeliveryStatus处于(2,8)状态时
和(ISNULL(s.Limit2,0)+1>=u.Limit2)然后是1
其他0
最后,,
cam.ContentType ContentType
来自@tempt
使用(NOLOCK)连接活动cam
在t.idcampaign=cam.idcampaign上
使用(NOLOCK)加入DBO.Subscriber s
在s.IdUser=cam.IdUser上
使用(NOLOCK)加入DBO.[User]u
在s.idUser=u.idUser上
加入DBO.cdoi与(NOLOCK)
在cdoi.IdSubscriber=s.IdSubscriber上
和cam.IdCampaign=cdoi.IdCampaign
其中s.IDSubscriberStatus<3
)结果
按结果分组。IdSubscriber,
result.IdDeliveryStatus,
结果:,
result.ContentType,
result.idSubscriberStatus
在内部查询中使用DISTINCT,在外部使用de group by,但继续返回重复的 所有三列,尝试使用case语句在上述语句中插入与“1”相同的值
以这种情况为例
when
.
[Status]=1
[LimitReached]=1
[IdSubscriber]=1
如前所述,您可以使用该结构和查询,只需将分组依据
添加到选择
。
您的select查询必须修改如下(仅作为示例):
请注意,max(cam.ContentType)
只是一个建议,因为您只发布了部分查询,所以必须仔细检查语法。
如果由于其他约束而无法进行分组,则必须修改约束或修改目标表的结构
结束语:除了胡乱猜测之外,没有足够的信息来做任何事情,但在我看来,表结构中有一些东西需要检查;可能必须更改主键或表名有误导性?
distinct
对选择列表中的所有列进行操作。由于您的select
包含的列比主键包含的列多,因此可能会发生重复。您可以向我们展示完整的查询吗?您需要添加一个GROUP BY
子句,以便获得唯一的IdSubscriber+Status+LimitReach。但是我在select上使用了一个DISTINCE子句,这不会删除所有重复的?
SELECT s.IdSubscriber,
CASE cdoi.Status
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 1
WHEN 8 THEN 2
END AS Status,
CASE
WHEN CONDITION1 THEN 1
WHEN CONDITION2 THEN 1
WHEN CONDITION3 THEN 1
ELSE 0
END LimitReached,
max(cam.ContentType), <----- here the change
@Date
FROM Tables join
GROUP BY s.IdSubscriber,
CASE cdoi.Status
WHEN 0 THEN 0
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 1
WHEN 8 THEN 2
END AS Status,
CASE
WHEN CONDITION1 THEN 1
WHEN CONDITION2 THEN 1
WHEN CONDITION3 THEN 1
ELSE 0
END LimitReached