SQL Server 根据一列的值删除另一列的重复项

krcsximq  于 2023-01-20  发布在  其他
关注(0)|答案(2)|浏览(214)

我有一个包含如下数据的表
| 订单ID|代码|瓦尔|
| - ------|- ------|- ------|
| 1个|代码1|美国广播公司|
| 第二章|代码2|定义|
| 三个|代码1|美国汽车协会|
| 三个|代码2|bbb|
预期
| 订单ID|代码|瓦尔|
| - ------|- ------|- ------|
| 1个|代码1|美国广播公司|
| 第二章|代码2|定义|
| 三个|代码2|bbb|
现在,我希望以这样的方式获取OrderId:OrderId应该只有一个Code值。如果OrderId有多个Code值,则Code 2优先。因此,我的最终结果应该如下所示:OrderId 3应该只有一个值为Code 2的记录,如何在T-SQL中查询。我尝试了以下查询,但不确定之后如何继续

select OrderId, Code, count(*)
from Table1
group by OrderId, Code
0mkxixxg

0mkxixxg1#

你可以使用ROW_NUMBER() OVER (PARTITION BY OrderId ORDER BY OrderCode desc) row_num的概念
例如:

select *
from (
    select *
        , row_number() over (partition by orderId order by ordercode desc) row_num
    from #OrderTemp
) Orders
where row_num = 1
cdmah0mi

cdmah0mi2#

在编辑之前,您的原始问题的答案是MAXGROUP BY的简单查询:

SELECT 
    OrderId, 
    MAX(Code) AS Code
FROM yourtable
GROUP BY OrderId
ORDER BY OrderId;

如果根据您的新要求需要选择更多列,我们可以使用上面的查询作为JOIN的子查询:

SELECT 
    y.OrderId, 
    y.Code, 
    y.Val
FROM yourtable y
INNER JOIN (
    SELECT 
        OrderId, 
        MAX(Code) AS Code
    FROM yourtable
    GROUP BY OrderId
) AS sub ON y.OrderId = sub.OrderId
    AND y.Code = sub.Code
ORDER BY y.OrderId;

但是这会变得很长,读起来很糟糕。因此,使用窗口函数应该是首选。
但还有一个可能的问题需要解决:
如果每个OrderId可能出现大量代码,我们应该小心使用这个简单的MAXROW_NUMBER概念,因为上面的查询将获取Code2,而不是Code10作为最高代码(如果两者都出现),这是因为它是一个字符串,而不是数字。
我想这不是我们的本意。我们可以通过找出单词code后面的最大数字来解决这个问题。所以我们可以在这里使用SUBSTRINGROW_NUMBER来做这样的事情:

SELECT orderId, code, val
FROM (
  SELECT 
    orderId, code, val,
    ROW_NUMBER() OVER 
      (PARTITION BY orderId 
      ORDER BY CAST(SUBSTRING(Code,5,LEN(code)-4) AS INT) DESC) row_num
    FROM yourtable
) Orders
WHERE row_num = 1;

因此,将取Code10而不是Code2
我们可以在这里复制这些东西:db<>fiddle
较长查询的想法也在fiddle中显示,但正如前面所说,这不方便,也不好读,所以我不推荐它。

相关问题