SQL Server 仅基于表的一列消除重复值

vyswwuz2  于 2022-12-22  发布在  其他
关注(0)|答案(4)|浏览(173)

我的疑问:

SELECT sites.siteName, sites.siteIP, history.date
FROM sites INNER JOIN
     history ON sites.siteName = history.siteName
ORDER BY siteName,date

输出的第一部分:

如何删除siteName列中的重复项?我只想保留基于date列的更新项。
在上面的示例输出中,我需要第1、3、6、10行

fae0ux8s

fae0ux8s1#

这就是窗口函数row_number()派上用场的地方:

SELECT s.siteName, s.siteIP, h.date
FROM sites s INNER JOIN
     (select h.*, row_number() over (partition by siteName order by date desc) as seqnum
      from history h
     ) h
    ON s.siteName = h.siteName and seqnum = 1
ORDER BY s.siteName, h.date
c3frrgcw

c3frrgcw2#

从您的示例中可以合理地假设siteIP列由siteName列确定(即每个站点只有一个siteIP)。如果确实如此,则有一个使用group by的简单解决方案:

select
  sites.siteName,
  sites.siteIP,
  max(history.date)
from sites
inner join history on
  sites.siteName=history.siteName
group by
  sites.siteName,
  sites.siteIP
order by
  sites.siteName;

但是,如果我的假设不正确(也就是说,一个站点可能有多个siteIP),那么从您的问题中就不清楚您希望查询在第二列中返回哪个siteIP

select
  sites.siteName,
  min(sites.siteIP),
  max(history.date)
from sites
inner join history on
  sites.siteName=history.siteName
group by
  sites.siteName
order by
  sites.siteName;
kcugc4gi

kcugc4gi3#

我使用以下模式解决此类查询:

SELECT *
FROM t
WHERE t.field=(
  SELECT MAX(t.field) 
  FROM t AS t0 
  WHERE t.group_column1=t0.group_column1
    AND t.group_column2=t0.group_column2 ...)

也就是说,它将选择字段值为最大值的记录。为了将它应用于您的查询,我使用了公共表表达式,这样我就不必重复JOIN两次:

WITH site_history AS (
  SELECT sites.siteName, sites.siteIP, history.date
  FROM sites
  JOIN history USING (siteName)
)
SELECT *
FROM site_history h
WHERE date=(
  SELECT MAX(date) 
  FROM site_history h0 
  WHERE h.siteName=h0.siteName)
ORDER BY siteName

需要注意的是,只有在计算最大值的字段是唯一的情况下,它才有效,在示例中,date字段对于每个siteName都应该是唯一的。也就是说,如果IP不能在每毫秒内多次更改。根据我的经验,这是常见的情况,否则你不知道哪个记录是最新的。如果history表具有(site, date)的唯一索引,则该查询也非常快,可以使用history表上的索引范围扫描,该索引范围扫描仅扫描第一项。

kxe2p93d

kxe2p93d4#

这是可以删除重复列值的最简单SQL

DELETE FROM table WHERE COUNT(column_name) > 1;

table是表的名称,column_name是不希望重复的列的名称。

相关问题