Sql 如何避免获取重复信息?

Sql 如何避免获取重复信息?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两张桌子 CustomerId, Name 1 pete 2 dave 3 jon CustomerId, Role 1 1 1 2 2 1 3 2 3 3 我希望select以以下格式返回数据 Name, Role pete 1 null 1 dave 2 jon 2 null 3 基本上,当我

我有两张桌子

CustomerId, Name   
1           pete
2           dave
3           jon


CustomerId, Role
1           1
1           2
2           1
3           2
3           3
我希望select以以下格式返回数据

Name,  Role
pete   1
null   1
dave   2
jon    2
null   3
基本上,当我查看一个包含数百条记录的select时,我希望能够只看到客户,然后在列表中看到它们后面的所有角色,并在列引用的表中没有重复项时返回null。

给你:

DECLARE @t TABLE
(
id INT,
Name VARCHAR(20),
Role INT
)

INSERT INTO @t
    SELECT ROW_NUMBER() OVER(ORDER BY Names.CustomerID, Roles.Role), Names.Name, Roles.Role 
    FROM @names AS Names
        INNER JOIN @roles AS Roles ON Roles.CustomerId = Names.CustomerId

UPDATE @t
SET Name = NULL
FROM @t Temp1
WHERE EXISTS(SELECT TOP 1 1 FROM @t Temp2 WHERE Temp2.Name = Temp1.Name AND Temp2.id < Temp1.id)

SELECT * FROM @t
我的结果与你的不同,因为我怀疑你有一个错别字交换,第一个null和dave被交换:

Name,  Role
pete   1
null   2
dave   1
jon    2
null   3
编辑:考虑到这一点,您实际上完全可以不使用临时表:

SELECT CASE WHEN row_no = 1 THEN Name ELSE NULL END AS Name, Role
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY Names.CustomerID ORDER BY Names.CustomerID, Roles.Role) As row_no, Names.Name, Roles.Role FROM @names AS Names
INNER JOIN @roles AS Roles ON Roles.CustomerId = Names.CustomerId
) x

我用行号来给名字编号,只为第一个RN=1我写名字。我用的是。。。因为我喜欢使用它们,而不是直接编写嵌套查询:-

我不明白期望的结果是如何得到的。我也不明白这就是我在论坛上发布它的原因:-我的意思是你用什么逻辑来定义期望的结果?我不清楚为什么Role=1有pete,null,但是Role=2有dave,jon,我看到你接受的答案与你所说的有所不同!这是一个很好的解决方案,非常感谢。我要弄清楚这些分区是如何工作的,并在我的查询中使用它……这只是一个简单的问题,为什么你要使用tablename而不仅仅是tablename?@Pete2k,因为我在SQL server上创建临时表来运行测试。这样我以后就不用把它们扔了。以开头的表是本地临时表。读这里
SELECT CASE WHEN row_no = 1 THEN Name ELSE NULL END AS Name, Role
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY Names.CustomerID ORDER BY Names.CustomerID, Roles.Role) As row_no, Names.Name, Roles.Role FROM @names AS Names
INNER JOIN @roles AS Roles ON Roles.CustomerId = Names.CustomerId
) x
-- TEST DB PREPARATION!!!

DROP TABLE #Names
DROP TABLE #Roles

CREATE TABLE #Names
(
    CustomerId INT,
    Name VARCHAR(1000)
)

CREATE TABLE #Roles
(
    CustomerId INT,
    Role Int
)

INSERT INTO #Names VALUES (1, 'pete')
INSERT INTO #Names VALUES (2, 'dave')
INSERT INTO #Names VALUES (3, 'jon')

INSERT INTO #Roles VALUES (1, 1)
INSERT INTO #Roles VALUES (1, 2)
INSERT INTO #Roles VALUES (2, 1)
INSERT INTO #Roles VALUES (3, 2)
INSERT INTO #Roles VALUES (3, 3)

-- HERE BEGINS THE REAL CODE!!!

; WITH Base AS
(
    SELECT #Names.CustomerId, Name, Role, ROW_NUMBER() OVER (PARTITION BY #Names.CustomerId ORDER BY Role) RN FROM #Names INNER JOIN #Roles ON #Names.CustomerId = #Roles.CustomerId 
)

SELECT CustomerId, CASE WHEN RN = 1 THEN Name END Name, Role FROM Base