如何比较同一SQL表的多行

时间:2017-02-05 03:14:37

标签: sql-server

假设我有一个如下所示的SQL Server表:

jQuery(document).ready(function(){
  var current = 1;
  // Next
  jQuery('.button_1').click(function(){
    jQuery('.' + current).fadeOut('fast');
    current = current % 3 + 1;
    jQuery('.' + current).fadeIn('slow');
    return false;
  });
  // Previous
  jQuery('.button_2').click(function () {
    jQuery('.' + current).fadeOut('fast');
    current--;
    if (current < 1) current = 3;
    jQuery('.' + current).fadeIn('slow');
  })
});

我想比较行以找到具有特定数据匹配的行。在这种情况下,我想识别具有匹配id,valB和valC的行,因此它应该只找到最后两行。 valA列的内容将被忽略。

然后我想删除两行中的一行,然后根据需要调整valA列。我的麻烦是识别匹配的行。

从本网站上的许多其他类似问题中,我尝试了类似的各种事情:

id   valA   valB   valC
-----------------------
1    1      2      3
2    4      5      6
3    7      8      9
3    10     11     12
4    13     14     15
4    16     14     15

但我最终获得了所有四个ID。我不知道为什么。即使这样可行,我仍然不确定如何继续更新和删除我需要对找到的所有匹配行进行的操作。有什么建议?感谢。

5 个答案:

答案 0 :(得分:1)

我认为你很亲密。您只需要排除您不想要的行:

SELECT DISTINCT A.id
FROM newtable A INNER JOIN
     newtable B
     ON A.id = B.id
WHERE A.valB = B.valB AND
      A.valC = B.valC AND
      A.valA <> B.valA;

答案 1 :(得分:1)

你也可以使用 HASHBYTES 。如果你有这些类型的查询,很多索引Foo列将有助于比较..

DEMO HERE

HASHBYTES

或者你可以使用DenseRank ..

create table #temp
(
id int,
vala int,
valb int,
valc int
)

insert into #temp
select 1,2,3,4
union all
select 4,8,10,12
union all
select 1,5,3,4

;With cte
as
(
select *,
dense_rank() over (  order by (HASHBYTES('SHA2_512',CONCAT(id,valb,valc)))) as rownum
from #temp
)
select * from cte where rownum>1

答案 2 :(得分:1)

  

...我的麻烦在于识别匹配的行。

要选择匹配的行,请使用:

public class Service
{
    public IList<Product> GetProducts(string currentUserRole)
    {
        // compare against Product's AllowedGroups
        return this.dataRepo.Products.Where(product => product.AllowedGroups.Contains(currentUserRole)).ToList();
    }

    public Product GetProduct(int productId, string currentUserRole)
    {
        // compare against Product's AllowedGroups
        var product = this.dataRepo.Products.FirstOrDefault(product => product.Id == productId);

        if (!product.AllowedGroups.Contains(currentUserRole))
        {
          throw new AuthorizationException("{0} not allowed on {1}", currentUserRole, product.Name);
        }
    }
}
  

......我还不确定如何继续更新和删除操作...

;with x as (

select *, count(*) over (partition by id, valb, valc) as N from YourTable

)


-- matching values
select x.id, x.vala, x.valb, x.valc from x where x.N > 1

我建议先做一个选择,看看会删除什么。

  

小提琴选择匹配:http://sqlfiddle.com/#!6/ae27b/5

     

小提琴删除:http://sqlfiddle.com/#!6/ae27b/2

     

在原始表格中包含记录的ROW_NUMBER(按ID排序):http://sqlfiddle.com/#!6/ae27b/14

答案 3 :(得分:0)

如果你只需要至少有两行具有相同valb和valc的id,你可以使用它:

select distinct 
    id
from t
group by
    id, valb, valc
having count(*) > 1;

如果您还需要获取其他列,可以使用窗口函数count,如下所示:

select
    *
from (
    select
        t.*,
        count(*) over (partition by id, valb, valc) cnt
    from t
) t where cnt > 1;

答案 4 :(得分:0)

告诉你的要求更多,比如你要传递的参数等等

你可以试试这个,

declare @t table(id int,valA int,valB int,valC int)
insert into @t values
(1  ,  1   ,   2   ,   3 )
,(2  ,  4   ,   5   ,   6 )
,(3  ,  7   ,   8   ,   9 )
,(3  ,  10  ,   11  ,   12)
,(4  ,  13  ,   14  ,   15)
,(4  ,  16  ,   14  ,   15)

;With CTE as
(
select * ,row_number()over(partition by id,valb,valc order by id)rn
from @t
)
,CTE1 as
(
select * from cte   
where rn>1
)
select * from @t t
where EXISTS(
select id from cte1 c where t.id=c.id)