标识SQL Server表中重复行组合的ID

标识SQL Server表中重复行组合的ID,sql,sql-server,Sql,Sql Server,我在SQL Server中有下表,表示我的产品的“构建”。一个产品可以由单个或多个型号ID、其各自的型号年份(可以为空,因为我并不总是拥有此信息)和每个产品的数量组合而成 CREATE TABLE [TD].[PRODUCT_BUILD] ( [PRODUCT_BUILD_ID] int identity NOT NULL , [PRODUCT_ID] int NOT NULL , [MODEL_ID] int NOT

我在SQL Server中有下表,表示我的产品的“构建”。一个产品可以由单个或多个
型号ID
、其各自的
型号年份
(可以为空,因为我并不总是拥有此信息)和每个产品的
数量
组合而成

CREATE TABLE [TD].[PRODUCT_BUILD]
(
    [PRODUCT_BUILD_ID]     int identity NOT NULL ,
    [PRODUCT_ID]           int NOT NULL ,
    [MODEL_ID]             int NOT NULL ,
    [MODEL_YEAR]           smallint NULL ,
    [QUANTITY_PER_PRODUCT] tinyint NOT NULL ,

    CONSTRAINT [PK_tbl_PRODUCT_BUILT] 
        PRIMARY KEY CLUSTERED ([PRODUCT_BUILD_ID] ASC),
    CONSTRAINT [FK_727] 
        FOREIGN KEY ([PRODUCT_ID])  REFERENCES [TD].[PRODUCT]([PRODUCT_ID]),
    CONSTRAINT [FK_730] 
        FOREIGN KEY ([MODEL_ID])  REFERENCES [TD].[MODEL]([MODEL_ID])
)
SELECT <TOP (1)> --<---Optional
  PRODUCT_ID
FROM 
  [TD].[PRODUCT_BUILD] as pb
WHERE EXISTS
(
  SELECT 1
  FROM 
    [TD].[PRODUCT_BUILD] as pb2
  WHERE
    pb2.PRODUCT_ID = @ProductID
    AND pb.MODEL_ID = pb2.MODEL_ID
    AND pb.MODEL_YEAR = pb2.MODEL_YEAR
    AND pb.QUANTITY_PER_PRODUCT = pb2.QUANTITY_PER_PRODUCT
    AND pb.PRODUCT_ID <> pb2.PRODUCT_ID
)
假设给我一个
PRODUCT\u ID
值作为变量
@ProductID
,我想找到第一个找到的
PRODUCT\u ID
,如果它存在的话,它是
MODEL\u ID
的重复组合,
MODEL\u YEAR
每个产品的数量
匹配与
@ProductID
相关的精确组合

有了
@ProductID=99
和下表,我想选择返回
产品\u ID=51

+------------------+------------+----------+------------+----------------------+
| PRODUCT_BUILD_ID | PRODUCT_ID | MODEL_ID | MODEL_YEAR | QUANTITY_PER_PRODUCT |
+------------------+------------+----------+------------+----------------------+
|                1 |         24 |       26 |            |                    1 |
|                2 |         50 |       26 |       2017 |                    1 |
|                3 |         50 |       34 |       2019 |                    2 |
|                4 |         51 |       26 |            |                    1 |
|                5 |         51 |       34 |       2019 |                    2 |
|                6 |         99 |       26 |            |                    1 |
|                7 |         99 |       34 |       2019 |                    2 |
|                8 |         13 |       26 |            |                    2 |
|                9 |         13 |       34 |       2019 |                    2 |
|               10 |          4 |       26 |            |                    1 |
+------------------+------------+----------+------------+----------------------+

一种方法是使用
WHERE EXISTS
子句。这将返回所有与传递的参数匹配的重复值。如果您只需要一个,您可以将
TOP(1)
添加到外部
SELECT

CREATE TABLE [TD].[PRODUCT_BUILD]
(
    [PRODUCT_BUILD_ID]     int identity NOT NULL ,
    [PRODUCT_ID]           int NOT NULL ,
    [MODEL_ID]             int NOT NULL ,
    [MODEL_YEAR]           smallint NULL ,
    [QUANTITY_PER_PRODUCT] tinyint NOT NULL ,

    CONSTRAINT [PK_tbl_PRODUCT_BUILT] 
        PRIMARY KEY CLUSTERED ([PRODUCT_BUILD_ID] ASC),
    CONSTRAINT [FK_727] 
        FOREIGN KEY ([PRODUCT_ID])  REFERENCES [TD].[PRODUCT]([PRODUCT_ID]),
    CONSTRAINT [FK_730] 
        FOREIGN KEY ([MODEL_ID])  REFERENCES [TD].[MODEL]([MODEL_ID])
)
SELECT <TOP (1)> --<---Optional
  PRODUCT_ID
FROM 
  [TD].[PRODUCT_BUILD] as pb
WHERE EXISTS
(
  SELECT 1
  FROM 
    [TD].[PRODUCT_BUILD] as pb2
  WHERE
    pb2.PRODUCT_ID = @ProductID
    AND pb.MODEL_ID = pb2.MODEL_ID
    AND pb.MODEL_YEAR = pb2.MODEL_YEAR
    AND pb.QUANTITY_PER_PRODUCT = pb2.QUANTITY_PER_PRODUCT
    AND pb.PRODUCT_ID <> pb2.PRODUCT_ID
)
选择--您可以试试这个

DECLARE @ProductID INT = 99

SELECT TOP 1 WITH TIES PRODUCT_BUILD_ID , PRODUCT_ID , MODEL_ID , MODEL_YEAR , QUANTITY_PER_PRODUCT FROM (
    SELECT T1.* ,COUNT(*) OVER(PARTITION BY T1.PRODUCT_ID ) AS CNT1, T2.CNT2  FROM [PRODUCT_BUILD] T1 
        INNER JOIN ( SELECT *,  COUNT(*) OVER() AS CNT2 FROM [PRODUCT_BUILD] WHERE PRODUCT_ID = @ProductID ) AS T2 
                ON T1.MODEL_ID  = T2.MODEL_ID AND 
                   ISNULL(T1.MODEL_YEAR,'') = ISNULL(T2.MODEL_YEAR,'') AND 
                   T1.QUANTITY_PER_PRODUCT = T2.QUANTITY_PER_PRODUCT 
) X
WHERE CNT1 = CNT2
ORDER BY PRODUCT_ID
结果:

PRODUCT_BUILD_ID PRODUCT_ID  MODEL_ID    MODEL_YEAR QUANTITY_PER_PRODUCT
---------------- ----------- ----------- ---------- --------------------
4                51          26          NULL       1
5                51          34          2019       2

提示:
ROW_NUMBER()OVER()。