0

这里的 SQL 菜鸟——我想在一个月内比较,有多少人改了姓。我的技能限制了我,所以我能想到的最简单的方法是运行 2 个查询:

Query 1:
SELECT firstname, lastname
FROM names_dataset
WHERE date='2013-05-27' 

Query 2:
SELECT firstname, lastname
FROM names_dataset
WHERE date='2013-04-27'

Result query 1:
John        Smith
Michael     Johnson
James       Williams

Result query 2:
John        Smith
Michael     Johnson
James       Brown

我想要的唯一结果是“James Brown”,它在不同的日期更改了 col2。

我从两个查询中得到了很多重复的结果(没有更改名称的 ppl),我如何只过滤掉 col2 更改的行?

4

4 回答 4

1

鉴于您的名字字段是唯一的,这有效:

SELECT *
FROM (SELECT firstname, lastname
        FROM names_dataset
        WHERE date='2013-05-27'
     )day1
JOIN
     (SELECT firstname, lastname
        FROM names_dataset
        WHERE date='2013-04-27')
     )day2
ON day1.firstname = day2.firstname
WHERE day1.lastname <> day2.lastname

这将返回所有内容,如果您只想要“James Brown”,那么您可以将选择部分更改为:

SELECT day2.firstname, day2.lastname
于 2013-05-28T19:50:12.073 回答
1
    SELECT t1.firstname,
           t1.lastname AS from_lastname,
           t2.lastname AS to_lastname
      FROM names_dataset AS t1
INNER JOIN names_dataset as t2
        ON t1.firstname = t2.firstname
     WHERE t1.date='2013-04-27' 
       AND t2.date='2013-05-27' 
       AND t1.lastname <> t2.lastname

这将提供在两个日期具有相同名字但姓氏不同的行列表。

于 2013-05-28T19:44:56.343 回答
0

SQL 小提琴演示

我为此使用了 SQL Server;我会通过自内连接来解决这个问题(注意 ID 字段仅用于测试目的)。按名字将表连接到自身,并查找名字和姓氏字段不匹配的位置。如果您怀疑名字可能已更改,请将此查询反转为名字。

最终查询:

SELECT *
FROM names n1
  INNER JOIN names n2 ON n1.FirstName = n2.FirstName
WHERE n1.LastName <> n2.LastName

或者,我的首选方法(SQL Fiddle 也是)是使用 ID 字段并与 ID 字段连接。这将捕获名字或姓氏的任何变化,并且总体上要简单得多,而且它解决了第一条评论,它正确地指出了一个问题 - 你怎么知道詹姆斯不是一个新人?这个查询:

SELECT *
FROM names n1
  INNER JOIN names n2 ON n1.ID = n2.ID
WHERE n1.FirstName <> n2.FirstName
  OR n1.LastName <> n2.LastName
于 2013-05-28T20:19:34.440 回答
0

也许您会发现这种方法很有帮助。我用它来将“添加”或“删除”分配给出现在一组但不是另一组的每一行:

select firstname, lastname,
       (case when MAX(which) = 'later' then 'ADDED'
             when MAX(which = 'earlier' then 'REMOVED'
             else '???'
        end)
from ((SELECT firstname, lastname, 'later' as which
       FROM names_dataset
       WHERE date='2013-05-27' 
      ) union all
      (select firstname, lastname, 'earlier'
       FROM names_dataset
       WHERE date='2013-04-27' 
      )
     ) t
group by firstname, lastname
having count(*) = 1;

它结合了来自两组的名称并计算出现一次的数字。如果事件发生在较晚的时间段内,则添加记录。如果仅在较早的时间段内,则将其删除。

此外,这是标准 SQL,因此它应该适用于大多数数据库。

于 2013-05-28T19:48:47.470 回答