Dies ist meine erste Frage hier, also entschuldige ich mich, wenn ich etwas falsch mache. Ich bin auch ein SQL-Amateur, also tut mir leid, wenn ich keinen Sinn mache. Ich arbeite mit SQL Server 2014.

Ich habe Daten in einem Datumsbereich (01.11.15 bis 30.11.15) und ich habe 3 Standortnamen: NY, LA, SF. Kann ich jeden dieser Namen für jedes Datum im Bereich in einer separaten Zeile anzeigen lassen?

Etwas wie das:

01.11.15 | NY
11/01/15 | LA
01.11.15 | SF
11/02/15 | NY
11/02/15 | LA
11/02/15 | SF
11/03/15 | NY
11/03/15 | LA
11/03/15 | SF
.
.
.
.
30.11.15 | NY
30.11.15 | LA
30.11.15 | SF

1
st33vemcqu33n 24 Dez. 2015 im 00:04

3 Antworten

Beste Antwort

Sehen Sie Ihren CTE:

WITH mycte
     AS
        (
     SELECT CAST('20151101' AS DATETIME
                ) DateValue
     UNION ALL
     SELECT DateValue + 1
     FROM mycte
     WHERE DateValue + 1 < '20151201'
        ),
     myNames
            (myName
            )
     AS
        (
     SELECT 'NY'
     UNION
     SELECT 'LA'
     UNION
     SELECT 'SF'
        )
     SELECT *
     FROM mycte m
          CROSS JOIN myNames mn;
1
Cetin Basoz 23 Dez. 2015 im 21:18

Angenommen, Datumsangaben befinden sich in einer Tabelle mit dem Namen myDates und Namen in einer Tabelle mit dem Namen myNames mit den Feldnamen myDate bzw. myName:

select d.myDate, n.myName
from myDates d
cross join myNames n
where d.MyDate >= '20151101' and d.myDate < '20151201'
0
Cetin Basoz 23 Dez. 2015 im 21:08

Versuche dies:

DECLARE @StartDate DATE = '20150111'
DECLARE @EndDate DATE = '20151130'
DECLARE @Diff INT = DATEDIFF(DAY, @StartDate, @EndDate)
PRINT @Diff

;WITH DateRangeCte AS (
    SELECT DATEADD(DAY, currDay - 1, @StartDate) AS RangeDate
    FROM ( 
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS currDay
        -- this table should have more records than range size
        FROM sys.messages                               
    ) nbrs
    WHERE currDay - 1 <= @Diff
)
SELECT RangeDate, LocationName
FROM DateRangeCte C 
    CROSS JOIN (
        SELECT 'NY' AS LocationName UNION ALL 
        SELECT 'LA' UNION ALL
        SELECT 'SF'
    ) Loc
go

Wie vorgeschlagen, kann DateRangeCte mit einem rekursiver CTE oder durch Durchlaufen einer "ausreichend großen" Tabelle (die Anzahl der Zeilen ist bekanntermaßen größer als die Intervallgröße). Ich habe sys.message gewählt, da es ziemlich groß ist (mehr als 200 KB), aber es wird sich auf die Leistung auswirken. Wenn die Leistung wichtig ist, wählen Sie rekursiven CTE (st33vemcqu33n's Antwort).

Außerdem habe ich CROSS mit einer "anonymen" Tabelle verbunden. Ich denke, diese Zustände werden in einer persistenten Tabelle gespeichert, sodass Sie die Verknüpfung mit dieser Tabelle kreuzen.

0
Alexei 23 Dez. 2015 im 21:22