id first middle last
1 Mike Tyson
2 Nikki Roy James
2 Nikki James
3 Rob
3 Rob Van
3 Rob Van Dam
选择语句的所需输出
id first middle last
1 Mike Tyson
2 Nikki Roy James
3 Rob Van Dam
我如何编写查询
答案 0 :(得分:0)
您首先要对ORDER BY进行排序,以使所有没有id
底部的中间行都没有中间名。例如,ORDER BY first ORDER BY middle
然后执行SELECT DISTINCT(*) FROM <table_name> WHERE (first IS NOT NULL) AND (last IS NOT NULL)
。如果每个id
都有中间名,它将抓住每个中间名的最后一个条目,否则它将不带中间名就抓取它的最后一个条目。假设每个人都有名字和姓氏。
答案 1 :(得分:0)
我将详细说明Ely的答案:
您首先要对ORDER BY进行排序,以使所有没有的行都有一个 中间名称位于每个ID的底部。例如ORDER 按第一个ORDER BY中点,然后执行SELECT DISTINCT(*)FROM 在哪里(第一个不为空)和(最后一个不为空)。这个 如果有一个ID,它将使用中间名获取每个ID的最后一个条目 否则,它将不使用中间名就将其抓取。假设 每个人都有名字和姓氏。
我注意到您的问题已被否决,但这是一个合理的问题,而且它并不像看起来的那么简单-更不用说解决您需求的多种方法了。我的想法是对相关数据使用CROSS JOIN。
这是一个简单的示例,希望可以将您引向正确的方向。您可以在SSMS中运行它。
首先,我创建了一个表变量并插入了示例数据,如下所示:
DECLARE @names TABLE ( [id] INT, [first] VARCHAR(50), [middle] VARCHAR(50), [last] VARCHAR(50) );
INSERT INTO @names (
[id], [first], [middle], [last]
)
VALUES
( 1, 'Mike', '', 'Tyson' )
, ( 2, 'Nikki', 'Roy', 'James' )
, ( 2, 'Nikki', '', 'James' )
, ( 3, 'Rob', '', '' )
, ( 3, 'Rob', 'Van', '' )
, ( 3, 'Rob', 'Van', 'Dam' );
然后,我编写了一个带有CROSS JOIN的SELECT,它为每个具有最完整数据的id返回一行:
SELECT DISTINCT
[n].[id]
, [fullNames].[first]
, [fullNames].[middle]
, [fullNames].[last]
FROM @names n
CROSS APPLY (
SELECT TOP 1
[@names].[first], [@names].[middle], [@names].[last]
FROM @names
WHERE
[@names].[id] = [n].[id]
ORDER BY
[@names].[first] DESC, [@names].[middle] DESC, [@names].[last] DESC
) AS [fullNames]
ORDER BY
[id];
哪个返回以下内容:
+-------------------------------+
| id | first | middle | last |
| ----+-------+--------+------- |
| 1 | Mike | | Tyson |
| 2 | Nikki | Roy | James |
| 3 | Rob | Van | Dam |
+-------------------------------+
注意:
初始的 SELECT DISTINCT 确保对 @names 结果集中的每一行仅返回一个唯一的“ id”值。
CROSS JOIN中使用的 TOP 1 捕获有关ID的单个记录,而每个列上的 ORDER BY DESC 确保具有该ID(WHERE [@names].[id] = [n].[id]
)的最完整数据的记录位于顶部。
我希望这会有所帮助。