【问题标题】:Get SQL Server result using subquery使用子查询获取 SQL Server 结果
【发布时间】:2020-05-10 06:14:22
【问题描述】:

我有一个像这样的Members 表:

PersonID    FirstName   Address      City      date
---------------------------------------------------------
    3       Rasanga     Skagen 21    South     2019-01-05

还有一个Persons 表:

PersonID  FirstName   Address     City       date
-------------------------------------------------------
   3      Rasanga     Skagen 21   South      2019-01-06
   1      Tom B.      Skagen 21   Colombo    2018-01-07
   2      Tom B.      Skagen 21   Colombo    2019-01-05

我想使用FirstName 列获取Members 表中不存在的Persons。为此,我正在使用此查询:

SELECT * 
FROM Persons p
WHERE NOT EXISTS (SELECT * FROM Members m WHERE m.FirstName = p.FirstName)

当我执行上述查询时,我得到了相同的名字和 2 条记录,但我的要求是如果有 2 条同名记录使用日期列检索最新记录。因此,上述情况应该是 Tom B.,记录为 2018-01-07。如果两条记录的日期相同,则应从 2 条记录中检索 1 条记录。

有人能解释一下怎么做吗?

【问题讨论】:

  • 你有personid,为什么还要用firstname加入?你需要更多解释你在做什么。

标签: sql sql-server subquery


【解决方案1】:

您可以使用left join 并检查Members.PersonIdnull

create table Members(PersonID int
, FirstName varchar(20)
, Address varchar(50)
, City varchar(50)
, Dtdate date)

insert into Members values
(3, 'Rasanga', 'Skagen 21', 'South', '2019-01-05')

Create table Persons(PersonID int
, FirstName varchar(20)
, Address varchar(50)
, City varchar(50)
, Dtdate date)

insert into Persons values
(3, 'Rasanga', 'Skagen 21', 'South', '2019-01-06'),
(1, 'Tom B.', 'Skagen 21', 'Colombo', '2018-01-07'),
(2, 'Tom B.', 'Skagen 21', 'Colombo', '2019-01-05')

Select Persons.* from Persons
left join Members on Persons.PersonID = Members.PersonID
where Members.PersonId is null

Demo

使用not exists可以检查如下。

SELECT Persons.*
FROM   Persons
WHERE  NOT EXISTS (SELECT 1 
                   FROM  Members 
                   WHERE  Persons.PersonID = Members.PersonID)

使用 in 运算符

SELECT * FROM Persons
WHERE PersonID NOT IN (
 SELECT PersonID FROM Members
)

要根据名字和日期获取唯一记录,您可以使用ROW_NUMBER() 函数使用以下查询。

;WITH cte
AS (
    SELECT Persons.*
       ,ROW_NUMBER() OVER (
        PARTITION BY Persons.FirstName ORDER BY Persons.Dtdate DESC
        ) AS RN
    FROM Persons
    LEFT JOIN Members ON Persons.PersonID = Members.PersonID
    WHERE Members.PersonId IS NULL )
SELECT *
FROM CTE
WHERE RN = 1

输出

PersonID    FirstName  Address     City     Dtdate     RN
----------------------------------------------------------
2           Tom B.     Skagen 21   Colombo  2019-01-05  1

【讨论】:

  • 嗨@Suraj Kumar 感谢您的回答。但我仍然得到 2 条记录,我的要求是如果有 2 条同名记录使用日期列检索最新记录。如果两条记录的日期相同,则应从 2 条记录中检索 1 条记录。
  • @RasangaAbeykoon 请使用ROW_NUMBER() 函数检查当前编辑。
【解决方案2】:

你可以使用窗口函数

SELECT T.PersonID,
       T.FirstName,
       T.Address,
       T.City,
       T.[Date]
FROM
(
  SELECT *, ROW_NUMBER() OVER(PARTITION BY FirstName ORDER BY [Date] DESC) RN
  FROM Persons
) T
WHERE NOT EXISTS
(
  SELECT 1
  FROM Members 
  WHERE FirstName = T.FirstName
) AND T.RN = 1;

这是db<>fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-01
    • 2023-03-25
    • 2016-11-17
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多