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