获取最早日期的SQL查询
我是SQL新手,有一个包含ID和服务日期的大型数据库,我需要编写一个查询,以给出每个ID拥有服务的第一个日期 我试过:获取最早日期的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和最早的服务日期。任何建议都将不胜感激 编辑:更准确地说,
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