繁体   English   中英

从同一个表sql中获取不同列的最新和最早值

[英]Get latest and earliest value of different column from same table sql

我有一张包含日期选择的表格。 我希望能够应用 WHERE 语句来返回一组它们,然后从一列中返回哪个日期最早,哪个是另一列中的最新日期。 这是一个示例表:

ID  StartDate   EndDate     Person   Subject
1   01/03/2010  03/03/2010   Paul    Math
2   12/05/2010  22/05/2010   Steve   Science
3   04/03/2010  08/03/2010   Paul    English

所以我想返回 Person = 'Paul' 的所有记录。 但是返回类似(最早的)StartDate = 01/03/2010(来自记录ID 1)和(最新的)EndDate = 08/03/2010(来自记录ID 3)和Subject = English来自最新的EndDate(来自记录3)。 我需要两行带有上述数据的 Paul 和 Id.Need all row with person = 'Paul'

预期结果 :

ID  StartDate   EndDate Person  Subject
1   2010-03-01  2010-03-08  Paul    English
3   2010-03-01  2010-03-08  Paul    English

您是否在以下 sql 查询中看到有关性能(数百万条记录)的任何问题:

 Select PT3.ID,PT4.EarliestStartDate AS StartDate,PT4.EndDate,PT4.Person,PT4.Subject from Data AS PT3 
Join( SELECT Top 1 with ties * FROM Data AS PT  
Join( SELECT PT1.Person as Person1, MIN(PT1.StartDate ) as EarliestStartDate FROM Data AS PT1 where Person ='Paul' group by PT1.Person)  AS PT2 ON  PT.Person =PT2.Person1WHERE Person  ='Paul'
  Order By Row_Number() over (Partition By PT.Person Order By PT.EndDate desc)) AS PT4 ON PT3.Person = PT4.Person 

这可以工作:

  1. 首先执行group by以获得每个人所需的日期。
  2. 将分组移至公共表表达式 ( cte )。
  3. 使用完整数据集重新连接以获取所有行。
  4. 对于每个结果记录,选择带有cross apply的相应主题。
  5. 可选:过滤所需的人( where子句)。

样本数据

create table Data
(
  ID int,
  StartDate date,
  EndDate date,
  Person nvarchar(10),
  Subject nvarchar(10)
);

insert into Data (ID, StartDate, EndDate, Person, Subject) values
(1, '2010-03-01', '2010-03-03', 'Paul',  'Math'),
(2, '2010-05-12', '2010-05-22', 'Steve', 'Science'),
(3, '2010-03-04', '2010-03-08', 'Paul',  'English');

解决方案

with cte as
(
  select min(d.StartDate) as StartDate,
         max(d.EndDate) as EndDate,
         d.Person
  from Data d
  group by d.Person
)
select d.Id,
       c.StartDate,
       c.EndDate,
       c.Person,
       x.Subject
from cte c
join data d
  on d.Person = c.Person
cross apply ( select top 1 d2.Subject
              from Data d2
              where d2.Person = c.Person
                and d2.EndDate = c.EndDate ) x
where d.Person = 'Paul'
order by d.Person;

小提琴看看它在行动。

这应该给你正确的价值观。

DECLARE @values TABLE (
    Id INT,
    StartDate DATETIME2,
    EndDate DATETIME2,
    Person NVARCHAR(MAX),
    Subject NVARCHAR(MAX))

INSERT INTO @values VALUES 
(1, '2010-03-01', '2010-03-03', 'Paul', 'Math'),
(2, '2010-05-12', '2010-05-22', 'Steve', 'Science'),
(3, '2101-03-04', '2010-03-08', 'Paul', 'English')

;WITH sort AS (
    SELECT
        Person,
        MIN(StartDate) OVER(PARTITION BY Person) StartDate,
        MAX(EndDate) OVER(PARTITION BY Person) EndDate,
        Subject,
        ROW_NUMBER() OVER(PARTITION BY Person ORDER BY EndDate DESC) rownum
    FROM @values v)

SELECT
    Person,
    StartDate,
    EndDate,
    Subject
FROM sort
WHERE rownum = 1

它会给你以下结果:

Person  MinStartDate    MaxEndDate   Subject
Paul    2010-03-01      2010-03-08   English
Steve   2010-05-12      2010-05-22   Science

如果您只关心选择 Pauls 数据,这应该就足够了:

SELECT 
   Person,
   MIN(startDate) AS Earliest, 
   MAX(EndDate) AS Latest, 
   (
      SELECT TOP 1 Subject 
      FROM Data
      WHERE Person = 'Paul'
      ORDER BY EndDate DESC
   ) AS Subject
FROM Data WHERE Person = 'Paul'

如果您想选择所有人,这应该有效:

SELECT 
   d1.Person,
   MIN(d1.startDate) AS Earliest, 
   MAX(d1.EndDate) AS Latest, 
   (
      SELECT TOP 1 d2.Subject 
      FROM Data d2
      WHERE d2.Person = d1.Person
      ORDER BY EndDate DESC
   ) AS Subject
FROM Data d1
GROUP BY d1.Person

编辑:您似乎希望表格中的每一行都有结果,而不是每人一个,但总是显示最早和最晚的日期。 这是你追求的吗?

SELECT 
   d1.Id,
   d1.Person,
   (
      SELECT MIN(d1.StartDate) AS Earliest
      FROM Data d2
      WHERE d2.Person = d1.Person
   ) AS Earliest,
   (
      SELECT MAX(d1.EndDate) AS Latest
      FROM Data d2
      WHERE d2.Person = d1.Person
   ) AS Latest,
   (
      SELECT TOP 1 d2.Subject 
      FROM Data d2
      WHERE d2.Person = d1.Person
      ORDER BY EndDate DESC
   ) AS Subject
FROM Data d1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM