SQL 按一列分组

SQL grouping by one column

我正在尝试合并两个表中的列,并让它在每一行上仅显示唯一名称(全名),同时删除重复名称。我使用了 SELECT DISTINCT ,它在一定程度上起作用,但它显示每个(文件 ID)的唯一名称。这仍然给我留下了整个重复项。

我本来比较喜欢用GROUP BY,结果报错"each group by expression must contain at least one column that is not an outer reference."不知道什么意思

抱歉,如果这很简单,但我才刚刚开始学习 SQL!

SELECT DISTINCT TOP 3000
    p.FileDateID as "File ID", 
    p.CategoryID as "Category ID", 
    fd.OrganizationID as "Organization"
    concat(p.FirstName, p.MiddleName, P.LastName) as "Full Name"
    p.FirstName as "First Name", 
    p.MiddleName as "Middle Name", 
    p.LastName as "Last Name",
    p.Title, 
    p.Street, 
    p.City, 
    p.State, 
    p.Zip, 
    p.WorkPhone as "Work Phone", 
    p.MobilePhone as "Mobile Phone", 
    p.EMail

FROM 
    byte.dbo.Party p

INNER JOIN
    byte.dbo.FileData fd ON fd.FileDataID = p.FileDataID

#   GROUP BY
#   5

ORDER BY
    4 ASC

;

I originally preferred to use GROUP BY, but it give an error "each group by expression must contain at least one column that is not an outer reference." I don't know what this means.

该错误实际上准确地解释了您的问题所在,以及您的方法存在缺陷的原因。它试图告诉您,您只能 select 作为分组依据的字段,其他所有内容都必须删除或聚合。

而这正是需要发生的事情,因为您抱怨如果您绕过分组机制并尝试 "outsmart" 它,您会得到重复的行,因为文件 ID 不同——当然它们是不同,这使整行成为新行。分组会阻止 select 完全使用该字段。

因此,您需要做的是确切地弄清楚您想要从数据库中获取哪些数据,因为如果您确实需要 ID,那么您将获得每一行。如果您只想要不同的名称,请适当地表达您的查询并使用 group by.

最后一点,这个:

ORDER BY
    4 ASC

现在你只是在犯傻。

假设我们将在结果 table 中获得唯一名称和其余列的最小值(值)。 如果给定全名的任何其他列中的值超过 1 个,我们将看到该列中返回的最小值。 如果给定全名的其他列之一中只有 1 个值,则 min() 是微不足道的,我们将看到该列返回一个值

SELECT DISTINCT TOP 3000
   min(p.FileDateID) as "File ID", 
   min(p.CategoryID) as "Category ID", 
   min(fd.OrganizationID) as "Organization"
   concat(p.FirstName, p.MiddleName, p.LastName) as "Full Name"
   min(p.FirstName) as "First Name", 
   min(p.MiddleName) as "Middle Name", 
   min(p.LastName) as "Last Name",
   min(p.Title) as Title,    
   min(p.Street) as Street, 
   min(p.City) as City, 
   min(p.State) as State, 
   min(p.Zip) as Zip, 
   min(p.WorkPhone) as "Work Phone", 
   min(p.MobilePhone) as "Mobile Phone", 
   min(p.EMail) as Email
FROM 
   byte.dbo.Party p
INNER JOIN
   byte.dbo.FileData fd ON fd.FileDataID = p.FileDataID
GROUP BY
   concat(p.FirstName, p.MiddleName, p.LastName)
ORDER BY 4 ASC
;