标识SQL Server表中重复行组合的ID
我在SQL Server中有下表,表示我的产品的“构建”。一个产品可以由单个或多个标识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
型号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()。