Sql server 选择“按唯一列区分”

Sql server 选择“按唯一列区分”,sql-server,distinct-values,unique-index,Sql Server,Distinct Values,Unique Index,例如,现在我有一个如下表: Col1 Col2 Col3 Col4 1 1 1 1 11 2 3 44 111 2 3 444 1111 3 3 3 我有另一个具有相同结构的表,只是它有一个唯一的索引,包括Col2和Col3。所以,我想从第一个表中选择并插入到第二个表中,但跳过具有相同唯一索引的记录。因此,我可以创建一个包含以下数据的新表: Co

例如,现在我有一个如下表:

Col1      Col2  Col3    Col4
1         1     1       1
11        2     3       44
111       2     3       444
1111      3     3       3
我有另一个具有相同结构的表,只是它有一个唯一的索引,包括Col2和Col3。所以,我想从第一个表中选择并插入到第二个表中,但跳过具有相同唯一索引的记录。因此,我可以创建一个包含以下数据的新表:

Col1      Col2  Col3    Col4
1         1     1       1
11        2     3       44
1111      3     3       3
我该怎么做


目前我正在使用Merge-Into,但在我的表有数百万条记录的情况下,速度非常慢

请尝试此查询,而不使用唯一索引/约束-

查询:

DECLARE @temp TABLE
(
       Col1 VARCHAR(10)
     , Col2 VARCHAR(10)
     , Col3 VARCHAR(10)
     , Col4 VARCHAR(10)
)

INSERT INTO @temp (Col1, Col2, Col3, Col4)
VALUES 
     ('1',     '1', '1', '1'),
     ('11',    '2', '3', '44'),
     ('111',   '2', '3', '444'),
     ('1111',  '3', '3', '3')

SELECT
      Col1 = MIN(Col1)
    , Col2
    , Col3
    , Col4 = MIN(Col4)
FROM @temp
GROUP BY
      Col2
    , Col3
Col1       Col2       Col3       Col4
---------- ---------- ---------- ----------
1          1          1          1
11         2          3          44
1111       3          3          3
输出:

DECLARE @temp TABLE
(
       Col1 VARCHAR(10)
     , Col2 VARCHAR(10)
     , Col3 VARCHAR(10)
     , Col4 VARCHAR(10)
)

INSERT INTO @temp (Col1, Col2, Col3, Col4)
VALUES 
     ('1',     '1', '1', '1'),
     ('11',    '2', '3', '44'),
     ('111',   '2', '3', '444'),
     ('1111',  '3', '3', '3')

SELECT
      Col1 = MIN(Col1)
    , Col2
    , Col3
    , Col4 = MIN(Col4)
FROM @temp
GROUP BY
      Col2
    , Col3
Col1       Col2       Col3       Col4
---------- ---------- ---------- ----------
1          1          1          1
11         2          3          44
1111       3          3          3

在没有唯一索引/约束的情况下尝试此查询-

查询:

DECLARE @temp TABLE
(
       Col1 VARCHAR(10)
     , Col2 VARCHAR(10)
     , Col3 VARCHAR(10)
     , Col4 VARCHAR(10)
)

INSERT INTO @temp (Col1, Col2, Col3, Col4)
VALUES 
     ('1',     '1', '1', '1'),
     ('11',    '2', '3', '44'),
     ('111',   '2', '3', '444'),
     ('1111',  '3', '3', '3')

SELECT
      Col1 = MIN(Col1)
    , Col2
    , Col3
    , Col4 = MIN(Col4)
FROM @temp
GROUP BY
      Col2
    , Col3
Col1       Col2       Col3       Col4
---------- ---------- ---------- ----------
1          1          1          1
11         2          3          44
1111       3          3          3
输出:

DECLARE @temp TABLE
(
       Col1 VARCHAR(10)
     , Col2 VARCHAR(10)
     , Col3 VARCHAR(10)
     , Col4 VARCHAR(10)
)

INSERT INTO @temp (Col1, Col2, Col3, Col4)
VALUES 
     ('1',     '1', '1', '1'),
     ('11',    '2', '3', '44'),
     ('111',   '2', '3', '444'),
     ('1111',  '3', '3', '3')

SELECT
      Col1 = MIN(Col1)
    , Col2
    , Col3
    , Col4 = MIN(Col4)
FROM @temp
GROUP BY
      Col2
    , Col3
Col1       Col2       Col3       Col4
---------- ---------- ---------- ----------
1          1          1          1
11         2          3          44
1111       3          3          3

我怀疑您能否比合并做得更好,但您可以尝试优化合并查询。是否可以发布您当前使用的查询?无论如何,在这种情况下,分析往往是快速的。例如,沿着以下路线的东西:

SELECT Col1, Col2, Col3, Col4
FROM (
    SELECT Col1,
           Col2,
           Col3,
           Col4,
           MIN(Col1) OVER (PARTITION BY COL2, COL3) AS MinCol1
    FROM someTable
) Temp
WHERE Col1 = MinCol1

我怀疑您能否比合并做得更好,但您可以尝试优化合并查询。是否可以发布您当前使用的查询?无论如何,在这种情况下,分析往往是快速的。例如,沿着以下路线的东西:

SELECT Col1, Col2, Col3, Col4
FROM (
    SELECT Col1,
           Col2,
           Col3,
           Col4,
           MIN(Col1) OVER (PARTITION BY COL2, COL3) AS MinCol1
    FROM someTable
) Temp
WHERE Col1 = MinCol1


如果对(Col2,Col3)确实有唯一索引/约束,则表数据处于无效状态,您将面临更大的问题。记录不应具有相同的唯一索引。如果他们这样做了,那就不是唯一的索引。如果您只是想为每个唯一的Col2/Col3组合选择一个值,那么您必须添加要选择的记录。只是“跳过”记录是没有意义的,因为默认情况下,假定数据不会以任何特定方式排序。对不起,我的错误,我已经编辑了我的问题。如果您确实对(Col2,Col3)有唯一索引/约束,那么表数据处于无效状态,并且您手头有一个更大的问题。记录不应该具有相同的唯一索引。如果他们这样做了,那就不是唯一的索引。如果您只是想为每个唯一的Col2/Col3组合选择一个值,那么您必须添加要选择的记录。只是“跳过”记录是没有意义的,因为默认情况下,数据被假定为不以任何特定方式排序。对不起,我的错误,我编辑了我的问题上面的数据只是一个例子,实际上,它是varchar数据类型,它也不是简单的1,2,3,这样也可以工作好的varchar,但是上面的查询可以很好地从不同的记录中选择数据。这几乎永远不会是你想要的。谢谢你,这已经足够好了。我想问您另一个问题,如果我像您一样在第一个表中使用group by,则会发生错误:列“Col1”在select列表中无效,因为它不包含在聚合函数或group by子句中。但是如果我使用一个临时表,就像你的答案一样,它是可以的。那么为什么会发生这种情况呢?如果我理解正确,只需将
Col1
放在
groupby
块中,或者为该列添加聚合函数。上面的数据只是一个示例,实际上,它是varchar数据类型,并且它也不是简单的1,2,3,这样也可以使用好的varchar,但是上面的查询可以很好地从不同的记录中选择数据。这几乎永远不会是你想要的。谢谢你,这已经足够好了。我想问您另一个问题,如果我像您一样在第一个表中使用group by,则会发生错误:列“Col1”在select列表中无效,因为它不包含在聚合函数或group by子句中。但是如果我使用一个临时表,就像你的答案一样,它是可以的。那么为什么会发生这种情况呢?如果我理解正确,只需将
Col1
放入
groupby
块中,或者为该列添加聚合函数。当我删除唯一索引并将所有记录插入新表时,插入2200万条记录只需大约1小时。但是如果我使用merge-into,它会花费我将近3个小时。所以我觉得很慢,(.关于这个问题,Devart有一个很好的答案,但有了这个答案,我必须先将数据插入临时表,然后再插入实际表。我想这也会很慢。Devart,你对我的情况有什么理想吗?我很难理解你的问题@user2500561。你能提供你的查询吗(
'Col1'无效
)记录集很小。啊,你上面的答案是正确的:)。我忘记了Col1=MIN(Col1)。很抱歉:)当我删除唯一索引并将所有记录插入新表时,插入2200万条记录只需大约1小时。但如果我使用merge-in,则需要将近3小时。所以我觉得速度非常慢:(.关于这个问题,Devart有一个很好的答案,但有了这个答案,我必须先将数据插入临时表,然后再插入实际表。我想这也会很慢。Devart,你对我的情况有什么理想吗?我很难理解你的问题@user2500561。你能提供你的查询吗(
'Col1'无效
)记录集很小。啊,您上面的答案是正确的:)。我忘记了Col1=MIN(Col1)。对此表示抱歉:)