如何选择包含更多信息的记录?

时间:2018-07-20 15:28:14

标签: sql-server

enter image description here

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

我如何编写查询

2 个答案:

答案 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])的最完整数据的记录位于顶部。

我希望这会有所帮助。