2010-11-15 2 views
6

Ich brauche eine Auswahl, um Monat und Jahr zurückzugeben Innerhalb eines bestimmten Datumsbereichs, wo ich das Jahr und den Monat eingeben würde und die Auswahl Monat und Jahr vom Datum I zurückgeben würde Eingabe bis heute.t-sql Wählen Sie alle Monate in einem Bereich von Jahren

Ich weiß, ich kann dies in einer Schleife tun, aber ich frage mich, ob es möglich ist, dies in einer Serie zu tun wählt?

Year Month 
---- ----- 
2010 1 
2010 2 
2010 3 
2010 4 
2010 5 
2010 6 
2010 7 

und so weiter.

+0

SQL Server 2008 –

Antwort

0
declare @date1 datetime, 
    @date2 datetime, 
    @date datetime, 
    @month integer, 
    @nm_bulan varchar(20) 

create table #month_tmp 
    (bulan integer null, keterangan varchar(20) null) 

select @date1 = '2000-01-01', 
     @date2 = '2000-12-31' 

select @month = month(@date1) 

while (@month < 13) 
Begin 
    IF @month = 1 
    Begin 
     SELECT @date = CAST(CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,0,@date1))-1),DATEADD(mm,0,@date1)),111) + ' 00:00:00' as DATETIME) 
    End 
    ELSE 
    Begin 
     SELECT @date = CAST(CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,@month -1,@date1))-1),DATEADD(mm,@month -1,@date1)),111) + ' 00:00:00' as DATETIME) 
    End 
    select @nm_bulan = DATENAME(MM, @date) 

    insert into #month_tmp 
    select @month as nilai, @nm_bulan as nama 

    select @month = @month + 1 
End 

select * from #month_tmp 
drop table #month_tmp 
go 
0

können Sie die folgende

SELECT DISTINCT YEAR(myDate) as [Year], MONTH(myDate) as [Month] 
FROM myTable 
WHERE <<appropriate criteria>> 
ORDER BY [Year], [Month] 
tun
+0

wie würden Sie verwenden, um die "entsprechenden Kriterien" können Sie beispielsweise zeigen ... wie alle Tage, 2009-12 bis heute –

3

Sie so etwas wie dieses verwenden können: http://blogs.msdn.com/b/sqlazure/archive/2010/09/16/10063301.aspx

das Äquivalent einer Zahlen-Tabelle Bereiche mit Datum zu erzeugen.

Aber könnten Sie bitte Ihre Eingaben und Ausgaben klären?

Möchten Sie ein Startdatum eingeben, z. B. '2010-5-1' und Enddatum, z. B. '2010-8-1', und es wird jeden Monat zwischen den beiden zurückgegeben? Möchten Sie den Startmonat und den Endmonat einbeziehen oder ausschließen?

Hier ist ein Code, den ich schrieb, der schnell ein integrierendes Ergebnis von jedem Monat zwischen zwei Daten erzeugen wird.

--Inputs here: 
DECLARE @StartDate datetime; 
DECLARE @EndDate datetime; 
SET @StartDate = '2010-1-5 5:00PM'; 
SET @EndDate = GETDATE(); 

--Procedure here: 
    WITH RecursiveRowGenerator (Row#, Iteration) AS (
     SELECT 1, 1 
     UNION ALL 
     SELECT Row# + Iteration, Iteration * 2 
     FROM RecursiveRowGenerator 
     WHERE Iteration * 2 < CEILING(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1)) 
     UNION ALL 
     SELECT Row# + (Iteration * 2), Iteration * 2 
     FROM RecursiveRowGenerator 
     WHERE Iteration * 2 < CEILING(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1)) 
    ) 
    , SqrtNRows AS (
     SELECT * 
     FROM RecursiveRowGenerator 
     UNION ALL 
     SELECT 0, 0 
    ) 
SELECT TOP(DATEDIFF(MONTH, @StartDate, @EndDate)+1) 
     DATEADD(month, DATEDIFF(month, 0, @StartDate) + A.Row# * POWER(2,CEILING(LOG(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1))/LOG(2))) + B.Row#, 0) Row# 
    FROM SqrtNRows A, SqrtNRows B 
ORDER BY A.Row#, B.Row#; 
+0

Ja das funktioniert .. –

1

--- Hier ist eine Version, die die Monatsende Termine der Regel für Abrechnungszwecke

DECLARE @StartDate datetime; 
DECLARE @EndDate datetime; 
SET @StartDate = '2010-1-1'; 
SET @EndDate = '2020-12-31'; 
--Procedure here: 





WITH RecursiveRowGenerator (Row#, Iteration)        
AS (  SELECT 1, 1   
UNION ALL   
SELECT Row# + Iteration, Iteration * 2   
    FROM RecursiveRowGenerator   
    WHERE Iteration * 2 < CEILING(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1)) 
    UNION ALL  SELECT Row# + (Iteration * 2), Iteration * 2 
      FROM RecursiveRowGenerator   
      WHERE Iteration * 2 < CEILING(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1))  ) 
       , SqrtNRows AS (  SELECT *   FROM RecursiveRowGenerator   
UNION ALL  SELECT 0, 0  ) 
SELECT TOP(DATEDIFF(MONTH, @StartDate, @EndDate)+1)   
      DateAdd(d,-1,DateAdd(m,1, DATEADD(month, DATEDIFF(month, 0, @StartDate) + A.Row# * POWER(2,CEILING(LOG(SQRT(DATEDIFF(MONTH, @StartDate, @EndDate)+1))/LOG(2))) + B.Row#, 0) )) 
Row# FROM SqrtNRows A, SqrtNRows B ORDER BY A.Row#, B.Row#; 
13

Gosh Leute ... mit einem „Zählen rekursiven CTE“ oder „RCTE“ verwendet wird als schlecht oder schlechter als mit einer Schleife. In dem folgenden Artikel finden Sie, warum ich das sage.

http://www.sqlservercentral.com/articles/T-SQL/74118/

Hier ist eine Möglichkeit, es ohne RBAR einschließlich der „hidden RBAR“ einer Zählung RCTE zu tun.

--===== Declare and preset some obviously named variables 
DECLARE @StartDate DATETIME, 
     @EndDate DATETIME 
; 
SELECT @StartDate = '2010-01-14', --We'll get the month for both of these 
     @EndDate = '2020-12-05' --dates and everything in between 
; 
WITH 
cteDates AS 
(--==== Creates a "Tally Table" structure for months to add to start date 
    -- calulated by the difference in months between the start and end date. 
    -- Then adds those numbers to the start of the month of the start date. 
SELECT TOP (DATEDIFF(mm,@StartDate,@EndDate) + 1) 
     MonthDate = DATEADD(mm,DATEDIFF(mm,0,@StartDate) 
        + (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1),0) 
    FROM sys.all_columns ac1 
    CROSS JOIN sys.all_columns ac2 
) 
--===== Slice each "whole month" date into the desired display values. 
SELECT [Year] = YEAR(MonthDate), 
     [Month] = MONTH(MonthDate) 
    FROM cteDates 
; 
+0

Ich mag Ihre Methode, es zu tun, aber am Ende gibt es immer noch nicht RBAR durch Aufrufen der YEAR() und MONTH() Funktionen in der Spalte MonthDate? – reverendlarry

+1

Hinter den Kulissen basiert alles in T-SQL tatsächlich auf einer Schleife der einen oder anderen Form, so dass alles als "RBR" bezeichnet wird. Da ich der Typ bin, der den Begriff prägte, ist hier, was "RBAR" zu bedeuten hat ...RBAR wird "ree-bar" ausgesprochen und ist ein "Modenism" für "Row By Agonizing Row". Der Begriff ist zu einer Code-Methode geworden, die aufgrund ihrer zeilenweisen Natur mehr Ressourcen benötigt oder längere Läufe verursacht, selbst wenn der Code tatsächlich "set-based" -Code ist. Da die meisten der eigentlichen Funktionen von SQL Server mit Maschinensprachengeschwindigkeiten arbeiten, würde ich sagen müssen: "Nein ... das ist nicht RBAR". ;-) –

+0

beste Antwort hier – MoreCoffee

1
DECLARE @Date1 DATE 
DECLARE @Date2 DATE 

SET @Date1 = '20130401' 
SET @Date2 = DATEADD(MONTH, 83, @Date1) 

SELECT DATENAME(MONTH, @Date1) "Month", MONTH(@Date1) "Month Number", YEAR(@Date1) "Year" 
INTO #Month 

WHILE (@Date1 < @Date2) 
BEGIN 
    SET @Date1 = DATEADD(MONTH, 1, @Date1) 
    INSERT INTO #Month 
    SELECT DATENAME(MONTH, @Date1) "Month", MONTH(@Date1) "Month Number", YEAR(@Date1) "Year" 
END 

SELECT * FROM #Month 
ORDER BY [Year], [Month Number] 

DROP TABLE #Month 
1

-Code erzeugt unter den Wert für den Bereich zwischen 21.em Juli 2013 und 15. Januar 2014. Ich verwende es normalerweise in SSRS Berichte zum Generieren von Suchwerten für den Monat Parameter.

declare 
    @from date = '20130721', 
    @to date = '20140115'; 

with m as (
select * from (values ('Jan', '01'), ('Feb', '02'),('Mar', '03'),('Apr', '04'),('May', '05'),('Jun', '06'),('Jul', '07'),('Aug', '08'),('Sep', '09'),('Oct', '10'),('Nov', '11'),('Dec', '12')) as t(v, c)), 

y as (select cast(YEAR(getdate()) as nvarchar(4)) [v] union all select cast(YEAR(getdate())-1 as nvarchar(4))) 

select m.v + ' ' + y.v [value_field], y.v + m.c [label_field] 
from m 
cross join y 
where y.v + m.c between left(convert(nvarchar, @from, 112),6) and left(convert(nvarchar, @to, 112),6) 
order by y.v + m.c desc 

Ergebnisse:

value_field  label_field 
--------------------------- 
Jan 2014  201401 
Dec 2013  201312 
Nov 2013  201311 
Oct 2013  201310 
Sep 2013  201309 
Aug 2013  201308 
Jul 2013  201307 
Verwandte Themen