SQL查询不同的内部联接问题

时间:2013-08-13 23:38:41

标签: sql sql-server

我遇到以下SQL INNER JOIN语句的问题。我可能在语法上遗漏了一些东西:

SELECT * from
(SELECT DISTINCT Name from Table.Names WHERE Haircolor='Red') uniquename
INNER JOIN
(SELECT * FROM Table.Names) allnames
ON uniquenames.Name = allnames.Name;

我想要所有名为Haircolor为“Red”的名字,但我不想要任何重复名称。

NAME        HAIRCOLOR       ADDRESS   PHONE       EMAIL
-----       ---------       -------  -----       -----
Joe         Red          123 Street  20768422    blah@example.com
Joe         Red         828 Street   703435422   blah4@example.com
Joe         Red         165 Street   10768422    blah3@example.com
Jamie       Blond       4655 Street  10568888    blah3@example.com
John        Brown       941 Street   40768422    blah5@example.com
Josephine   Red         634 Street   43444343    blah2@example.com
Josephine   Red         394 Street   43414343    blah7@example.com

查询应返回:

NAME        HAIRCOLOR       ADDRESS   PHONE       EMAIL
-----       ---------       -------  -----       -----
Joe         Red          123 Street  20768422    blah@example.com
Josephine   Red         634 Street   43444343    blah2@example.com

可能涉及GROUP BY?

8 个答案:

答案 0 :(得分:2)

可能:

select * from
(SELECT DISTINCT Name from Names WHERE Haircolor='Red') uniquenames
INNER JOIN
(SELECT * FROM Names) allnames
ON uniquenames.Name = allnames.Name

- 这取决于你真正想要看到的内容。

更新:SQLFiddle原始回答here

然而,更好的答案(如果使用MySQL)可能是:

select * from Names WHERE Haircolor='Red' group by Name

(请注意,为每个与头发颜色匹配的名称返回的特定行基本上是随机的。)

SQLFiddle here

进一步更新:对于SQLServer,请尝试:

with cte as
(select n.*, row_number() over (partition by name order by address) r
 from Names n WHERE Haircolor='Red')
select NAME, HAIRCOLOR, ADDRESS, PHONE, EMAIL 
from cte where r=1

- 这将返回每个名称的第一行(按地址,按字母顺序排列) - SQLFiddle here

答案 1 :(得分:1)

你在OP中的查询是一种非常迂回的说法

Select * From Names Where HairColor = 'Red'

将distinct子查询连接回原始表基本上否定了distinct关键字。你能否提供一些关于你在寻找什么的更多信息?一个例子是最好的。

答案 2 :(得分:1)

以下是ROW_NUMBER查询的示例。我现在无法测试它,因此可能会有一些错误。但是为了给你一个大致的想法,它从这样的查询开始:

select
  t.*,
  row_number() over (partition by name order by address) as rn
from
  table t
where
  haircolor = 'red'

这为每个红头提供了一行,添加了一列rn,在每组行中提供了具有相同name的序号。

然后,要从每个组中获取第一个,您只需添加外部查询以从第一个查询rn=1中选择行。

select * from (
  select
    t.*,
    row_number() over (partition by name order by address) as rn
  from
    table t
  where
    haircolor = 'red'
)
where rn=1

答案 3 :(得分:1)

SELECT * FROM names WHERE haircolor = 'red' GROUP BY name ORDER BY email ASC/DESC

从原始帖子中我看到你似乎正在加入一张桌子,我看不出你为什么要这样做

根据你的加入,有一些评论/答案,我认为这可能会令人困惑。您的查询过于复杂。

如果您碰巧有两个表,客户端和客户端功能/服务,那么我就能理解您为什么需要加入。但对于单个表,你根本不需要它。

根据评论更新

SELECT DISTINCT name, haircolor, address, phone, email FROM names WHERE haircolor = 'red'

如果返回结果无关紧要,那么这应该做你需要的。每个返回的行应该有一个不同的“名称”,所以你应该只返回两行,我没有测试它,但你可以试试。

这是小提琴,http://sqlfiddle.com/#!2/cc2e4/7

答案 4 :(得分:0)

根据OP的评论更新:如果您希望名称只出现一次,则需要在其他字段上有一个聚合子句,并按名称分组。

SELECT Name, MAX(Address), MAX(PhoneNumber)--, MAX(YourDesiredColumnHere)
FROM Table.Names 
WHERE Name IN (
      SELECT Name 
      FROM Table.Names 
      WHERE Haircolor = 'RED')
GROUP BY 
    Name

答案 5 :(得分:0)

除了这一点

Table.Names

看起来不对,为什么你不能这样做:

SELECT * from Table.Names WHERE Haircolor='Red'

我错过了什么吗?

答案 6 :(得分:0)

兄弟,尝试删除你的花括号,我希望下面的查询能够解决你的查询

SELECT DISTINCT Name from Table.Names
INNER JOIN (SELECT * FROM Table.Names) allnames
ON uniquenames.Name = allnames.Name
WHERE Haircolor='Red 

答案 7 :(得分:0)

如果你不关心你想要的愿望行,我会做那样的事情。

   SELECT tblName.* 
   FROM Table.Names as tblName
   INNER JOIN ( SELECT Name ,HairColor, MIN(Email)
                FROM Table.Names
                WHERE Haircolor='Red'
                GROUP BY Name ,HairColor) as tmp ON ( tmp.Email = tblName.Email)