【问题标题】:Filter on specific columns and return all columns过滤特定列并返回所有列
【发布时间】:2021-05-08 04:28:04
【问题描述】:

我正在尝试左连接两个表并从表一个中检索所有列,但根据一组列删除重复项。

SELECT A.*, B.impact
FROM #Site_one AS A WITH (NOLOCK)
LEFT JOIN #Progress AS B With (NOLOCK)
   ON lower(A.site_code) = lower(B.site_code)
GROUP BY A.date, A.operationid, A.worklocation, A.siteid, A.alias

这不起作用,因为 A 中的列需要聚合或添加到 group by 子句中。问题是我不想过滤这些列,也不希望它们聚合。

有没有办法选择 A 中的所有列和 B 中的影响列,并且仍然能够过滤掉 group by 子句中指定的列上的重复项?

任何指针/帮助将不胜感激。

【问题讨论】:

标签: sql sql-server tsql duplicates distinct


【解决方案1】:

并且仍然能够过滤掉 group by 子句中指定的列上的重复项

但是,数据库如何真正知道要丢弃哪些行?假设你有:

Person
John, 42, Stockbroker
John, 36, Train driver
John, 58, Retired
John, 58, Metalworker

而你认为“我想根据名称对那些进行重复数据删除”:

SELECT * FROM person GROUP BY name

那么数据库应该扔掉哪三个John

它不能为你决定;您必须编写查询以明确您想要保留或抛出的内容

你可以最大化一切:

SELECT name, MAX(age), MAX(job) FROM person GROUP BY name

这行得通.. 但它会给你一个原始数据中从未存在过的 John:

John, 58, Train driver

你可以说“我只会留下年龄最大的人”:

SELECT p.* 
FROM
  person p 
  INNER JOIN (SELECT name, max(age) as maxage FROM person GROUP BY name) maxp
  ON p.name = maxp.name AND p.age = maxp.maxage

.. 但是有两个人的最大年龄相同。

您的数据库可能有行号分析,这很好:

SELECT *, row_number() over(PARTITION BY name ORDER BY age DESC) rn
FROM person

您的一个 58 岁的 Johns 将获得第 1 行 - 无法确定是哪一个,但您可以丢弃所有 rn > 1 的行:

WITH x as (    
  SELECT *, row_number() over(PARTITION BY name ORDER BY age DESC) rn
  FROM person
)
SELECT name, age, job 
INTO newtable
FROM x
WHER rn = 1

..但是如果你丢弃了错误的约翰怎么办...


您将不得不再考虑一下,并准确指定要扔掉的东西...

【讨论】:

  • 这使得。我想这就是为什么我需要做某种聚合但想知道是否有办法解决它。谢谢你的详细解释
猜你喜欢
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
  • 2020-04-05
  • 2021-07-22
  • 2022-07-01
  • 1970-01-01
相关资源
最近更新 更多