获取最早日期的SQL查询

获取最早日期的SQL查询,sql,sql-server-2008,Sql,Sql Server 2008,我是SQL新手,有一个包含ID和服务日期的大型数据库,我需要编写一个查询,以给出每个ID拥有服务的第一个日期 我试过: SELECT dbo.table.ID, dbo.otherTable.ServiceDate AS EasliestDate FROM dbo.table INNER JOIN dbo.table.ID = dbo.otherTable.ID 但是输出是每个ID的每个服务,它有太多的结果需要排序。我希望输出只显示ID和最早的服务日期。任何建议都将不胜感激 编辑:更准确地说,

我是SQL新手,有一个包含ID和服务日期的大型数据库,我需要编写一个查询,以给出每个ID拥有服务的第一个日期

我试过:

SELECT dbo.table.ID, dbo.otherTable.ServiceDate AS EasliestDate
FROM dbo.table INNER JOIN dbo.table.ID = dbo.otherTable.ID
但是输出是每个ID的每个服务,它有太多的结果需要排序。我希望输出只显示ID和最早的服务日期。任何建议都将不胜感激

编辑:更准确地说,如果最早的服务日期在我指定的年份内,我要查找的输出是ID和服务日期。也就是说,如果ID=1在2015年和2016年有一项服务,并且我在2016年搜索ID,那么ID=1不应该出现在结果中,因为2015年有一项更早的服务

编辑:感谢所有帮助过这件事的人!我接受的答案完全符合我的要求。帕蒂非常荣幸,她详细阐述了如何按年份进一步筛选结果。

使用并获得每个ID的第一个日期:

SELECT  dbo.table.ID, 
        MIN(dbo.otherTable.ServiceDate) AS EasliestDate
FROM    dbo.table 
        INNER JOIN otherTable 
            ON dbo.table.ID = dbo.otherTable.ID
GROUP BY dbo.table.ID;

附录

关于评论中的一个问题:

我如何将其限制为仅显示在特定年份提供服务的人员

<> P>这将取决于您的确切要求,考虑下面的集合:

ID      ServiceDate
--------------------
1       2014-05-01
1       2015-08-01
1       2016-07-07
2       2015-08-19
如果您指定的年份是2016年,您只希望包含ID=1,但假设您仍然希望返回
2014-05-01
的第一个日期,那么您需要添加一个having子句和一个case语句来获得该值

DECLARE @Year INT = 2016;

DECLARE @YearStart DATE = DATEADD(YEAR, @Year - 1900, '19000101'),
        @YearEnd DATE = DATEADD(YEAR, @Year - 1900 + 1, '19000101');

SELECT @YearStart, @YearEnd

SELECT  t.ID, 
        MIN(o.ServiceDate) AS EasliestDate
FROM    dbo.table AS t
        INNER JOIN otherTable AS o
            ON o.ID = r.ID
GROUP BY t.ID
HAVING COUNT(CASE WHEN o.ServiceDate >= @YearStart 
                    AND o.ServiceDate < @YearEnd THEN 1 END) > 0;
在前者中,可以使用
ServiceDate
上的索引,而在后者中,必须对每个记录进行
DATEPART
计算,这可能会导致严重的性能问题

附录2

要执行以下操作:

我想要的正是我指定的年份中最早提供服务的ID

那么你需要一个having子句,与我之前发布的不同:

DECLARE @Year INT = 2016;

DECLARE @YearStart DATE = DATEADD(YEAR, @Year - 1900, '19000101'),
        @YearEnd DATE = DATEADD(YEAR, @Year - 1900 + 1, '19000101');

SELECT @YearStart, @YearEnd

SELECT  t.ID, 
        MIN(o.ServiceDate) AS EasliestDate
FROM    dbo.table AS t
        INNER JOIN otherTable AS o
            ON o.ID = r.ID
GROUP BY t.ID
HAVING  MIN(o.ServiceDate) >= @YearStart 
AND     MIN(o.ServiceDate) < @YearEnd;
然后,您可以将条件应用于视图:

SELECT  *
FROM    dbo.YourView
WHERE   EasliestDate >= '2015-01-01'
AND     EasliestDate < '2016-01-01';
选择*
从dbo.YourView
其中最容易的日期>='2015-01-01'
最容易的日期<'2016-01-01';
您需要使用“分组依据”语句。试试这个:
选择dbo.table.ID,Max(dbo.otherTable.ServiceDate)作为最晚日期,Min(dbo.otherTable.ServiceDate作为最早日期)
从dbo.table内部连接dbo.table.ID=dbo.otherTable.ID

group by dbo.table.ID

您必须在当前查询中包含WHERE:

SELECT dbo.table.ID, dbo.otherTable.ServiceDate AS EasliestDate
FROM dbo.table INNER JOIN dbo.table.ID = dbo.otherTable.ID
WHERE Month(dbo.otherTable.ServiceDate) = 1
或者您可以搜索年份(dbo.otherTable.ServiceDate)=2016 或者可以使用Day(dbo.otherTable.ServiceDate)=1


或特定日期。

使用嵌套语句获取最小日期,然后根据ID进行匹配

select t1.ID from table1 t1  INNER JOIN
       (
         SELECT ID, MIN(servicedate) MinServiceDate
         FROM table2
         GROUP BY ID
       ) t2 ON t1.ID = t2.ID

使用和获取记录。否则,您可以参考以更好地理解。

或者您可以使用“订购人”语句。太棒了!这很有效。虽然这不是我的问题,但我如何限制它只显示那些在特定年份有服务的人?我是否要添加一个“WHERE dbo.otherTable.serviceDate>=YYYY-MM-DD和from子句中限定表名。所以你真的应该去掉
dbo。
其他地方。@shawnt00 Microsoft SQL Server management Studio正在自动添加dbo。当我使用表名时,我想这并不奇怪,但它并不是最好的形式。您可能会考虑查看别名(AKA相关名称)。
CREATE VIEW dbo.YourView
AS
    SELECT  dbo.table.ID, 
            MIN(dbo.otherTable.ServiceDate) AS EasliestDate
    FROM    dbo.table 
            INNER JOIN otherTable 
                ON dbo.table.ID = dbo.otherTable.ID
    GROUP BY dbo.table.ID;
SELECT  *
FROM    dbo.YourView
WHERE   EasliestDate >= '2015-01-01'
AND     EasliestDate < '2016-01-01';
SELECT dbo.table.ID, dbo.otherTable.ServiceDate AS EasliestDate
FROM dbo.table INNER JOIN dbo.table.ID = dbo.otherTable.ID
WHERE Month(dbo.otherTable.ServiceDate) = 1
select t1.ID from table1 t1  INNER JOIN
       (
         SELECT ID, MIN(servicedate) MinServiceDate
         FROM table2
         GROUP BY ID
       ) t2 ON t1.ID = t2.ID