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