使用Distinct违反PRIMARY KEY约束

时间:2014-08-29 14:08:43

标签: sql sql-server sql-server-2008 tsql primary-key

我在下面的代码中遇到BULK INSERT的问题:

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子句。此脚本返回以下错误:

  

违反PRIMARY KEY约束' PK_SubscribersDeliveries'。不能   在对象' dbo.SubscribersDeliveries'。

中插入重复键

任何人都可以帮助我吗?

编辑:

当尝试按内部分组时,抛出一个错误,因为需要按cdoi.IdDeliveryStatus分组,我需要按CASE结果进行分组。

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

在内部查询中使用DISTINCT,在外部使用de group by,但继续返回重复!!!

2 个答案:

答案 0 :(得分:1)

正如已经指出的那样你可以使用那个结构&amp;查询只需向group by添加select即可。 你的选择查询必须修改如下(只是一个例子):

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部分:

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

请注意,max(cam.ContentType)只是一个建议,因为您只发布了部分查询,所以必须仔细检查语法。
如果由于其他约束而无法进行分组,则可以修改约束或修改目标表的结构。

结束语:没有足够的信息可以做任何事情,只是一个疯狂的猜测,但在我看来,有一些东西要检查表结构;也许必须更改主键或表名误导?

答案 1 :(得分:0)

所有三列,尝试使用case语句在上述语句中插入相同的值,如'1'。

考虑像

这样的情况
when
.
    [Status]=1 
    [LimitReached]=1 
    [IdSubscriber]=1