簡體   English   中英

使用Distinct違反PRIMARY KEY約束

[英]Violation of PRIMARY KEY constraint using Distinct

我在以下代碼中使用大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,但繼續返回重復項!!!

正如已經指出的那樣,您可以使用該結構和查詢,只需在select添加一個group by即可。 您的選擇查詢必須進行如下修改(僅作為示例):

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)只是一個建議,由於您僅發布了查詢的一部分,因此必須仔細檢查語法。
如果由於其他約束而無法分組,則必須修改約束或修改目標表的結構。

結束語:沒有足夠的信息可以做出瘋狂的猜測,但是我認為表結構中需要檢查一些內容; 也許必須更改主鍵或表名具有誤導性?

所有三列都嘗試使用case語句在上述語句中插入相同的值,例如'1'。

考慮這樣的情況

when
.
    [Status]=1 
    [LimitReached]=1 
    [IdSubscriber]=1 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM