How can I write a query to recursively execute with varying parameter values? Given the following query:

DECLARE @14DayWindow Datetime = DATEADD(day, -14, GETDATE())
DECLARE @90DayWindow Datetime = DATEADD(day, -90, GETDATE())

SELECT    * 
FROM      (SELECT   ID, COUNT(ID) 
           FROM     SomeTable 
           WHERE    SomeDate &gt; @14DayWindow 
           GROUP BY ID) as FourteenDayWindow
LEFT JOIN (SELECT   ID, COUNT(ID) 
           FROM     SomeTable 
           WHERE    SomeDate &gt; @90DayWindow 
           GROUP BY ID) as NinetyDayWindow
ON        FourteenDayWindow.ID = NinetyDayWindow.ID


Is there a way to re-write this query such that the SELECT subquery doesn't have to be written out for every window of time?  Ideally I would be able to supply an arbitrary number of parameters with each result being joined in sequence.  Possible?

EDIT: Output should be something like

ID | FourteenDayIDCount | NinetyDayIDCount
You can use an INLINE USER DEFINED FUNCTION for this purpose.

Have a look at Inline UDF rules:


The RETURNS clause contains only the keyword table. You do not have to define the format of a return variable, because it is set by the format of the result set of the SELECT statement in the RETURN clause.  
There is no function_body delimited by BEGIN and END.  
The RETURN clause contains a single SELECT statement in parentheses. The result set of the SELECT statement forms the table returned by the function. The SELECT statement used in an inline function is subject to the same restrictions as SELECT statements used in views.  
The table-valued function accepts only constants or @local_variable arguments





CREATE TABLE SomeTable(ID int, SomeDate datetime);

INSERT INTO SomeTable VALUES
(1, '20170301'),(1, '20170305'),(1, '20170310'),(1, '20170315'),(1, '20170320'),(1, '20170325'),(1, '20170329'),
(1, '20170401'),(1, '20170404'),(1, '20170412'),(1, '20170418'),(1, '20170422'),(1, '20170424'),(1, '20170430'),
(2, '20170303'),(2, '20170308'),(2, '20170312'),(2, '20170319'),(2, '20170323'),(2, '20170325'),(2, '20170330'),
(2, '20170405'),(2, '20170406'),(2, '20170412'),(2, '20170418'),(2, '20170422'),(2, '20170424'),(2, '20170430');
GO






CREATE FUNCTION dbo.fnCount(@MinDate datetime)
RETURNS TABLE
AS
RETURN
    SELECT   ID, COUNT(ID) NumID
    FROM     SomeTable
    WHERE    SomeDate &gt; @MinDate
    GROUP BY ID
GO






DECLARE @XDays Datetime = '20170401';
DECLARE @YDays Datetime = '20170308';

SELECT t1.ID, t1.NumID as [X-Days], t2.NumID as [Y-Days]
FROM   dbo.fnCount(@XDays) t1
JOIN   dbo.fnCount(@YDays) t2
ON     t1.ID = t2.ID
GO



ID | X-Days | Y-Days
-: | -----: | -----:
 1 |      6 |     12
 2 |      7 |     12



dbfiddle here