generieren Tagen ab Datum Bereich
Möchte ich eine Abfrage ausführen, wie
select ... as days where `date` is between '2010-01-20' and '2010-01-24'
- Und Rückgabe Daten wie:
Tage ---------- 2010-01-20 2010-01-21 2010-01-22 2010-01-23 2010-01-24
Es gibt keine anderen problem im Anhang zu dieser Frage. Die obige Frage ist das problem, mastering SQL Kurse.
Benötigen Sie nur eine Reihe von Daten basierend auf einem bestimmten Datum-Bereich?
Ich denke an eine Nutzung zu finden, Sie ein problem... Wenn man eine Aufgabe zu füllen, einige fehlende Datensätze in Ihrer Tabelle. Und Sie haben zum ausführen einer Abfrage für jeden Tag, ich denke so etwas wie
Ein Beispiel für seine Anwendung wäre, um Statistiken zu erzeugen, und fügen Sie eine Zeile für Termine Sie haben keine Daten auf. Wenn Sie dabei sind, eine Art von Gruppe -, indem Sie es sehr viel schneller, um tatsächlich zu generieren, die alle Informationen in SQL und fügen Sie ihn in welchem format auch immer Sie brauchen, statt dumping Ihre Daten, um Ihre Sprache aus und starten die Schleifen und das hinzufügen von Ihrem Leergut.
das ist genau, warum ich gespeichert diese Frage. Ich brauche das oben, LEFT JOIN-in-Daten, die nicht für bestimmte Termine.
Benötigen Sie nur eine Reihe von Daten basierend auf einem bestimmten Datum-Bereich?
Ich denke an eine Nutzung zu finden, Sie ein problem... Wenn man eine Aufgabe zu füllen, einige fehlende Datensätze in Ihrer Tabelle. Und Sie haben zum ausführen einer Abfrage für jeden Tag, ich denke so etwas wie
insert into table select ... as days date between '' and ''
Ein Beispiel für seine Anwendung wäre, um Statistiken zu erzeugen, und fügen Sie eine Zeile für Termine Sie haben keine Daten auf. Wenn Sie dabei sind, eine Art von Gruppe -, indem Sie es sehr viel schneller, um tatsächlich zu generieren, die alle Informationen in SQL und fügen Sie ihn in welchem format auch immer Sie brauchen, statt dumping Ihre Daten, um Ihre Sprache aus und starten die Schleifen und das hinzufügen von Ihrem Leergut.
das ist genau, warum ich gespeichert diese Frage. Ich brauche das oben, LEFT JOIN-in-Daten, die nicht für bestimmte Termine.
InformationsquelleAutor Pentium10 | 2010-01-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese Lösung verwendet keine Schleifen, Prozeduren oder temporären Tabellen. Die Unterabfrage erzeugt die Termine für die letzten 10.000 Tage, und könnte erweitert werden, um so weit zurück gehen, oder nach vorne, wie Sie wollen.
Ausgabe:
Hinweise auf die Leistung
Prüfung hier, die performance ist überraschend gut: die obige Abfrage dauert 0.0009 Sek.
Wenn wir erweitern, die Unterabfrage zum erzeugen ca. 100.000 zahlen (und damit etwa 274 Jahre im Wert von Daten), läuft es in 0.0458 Sek.
Übrigens, dies ist eine sehr tragbare Technik, die funktioniert mit den meisten Datenbanken mit kleineren Anpassungen.
SQL Fiddle Beispiel bei der Rückkehr 1.000 Tage
Sie werden sehen, eine bessere Leistung, wenn Sie ändern
UNION
zuUNION ALL
- es ist Zeit zu verschwenden überprüfung auf Duplikate zu entfernen, die nicht existieren. Es ist IMO zu kompliziert, obwohl wenn du gehst, zu konstruieren, ein resultset mit Gewerkschaften, warum nicht geben Sie nur das Datum und die mit ihm getan werden?warum nicht einfach das Datum anzugeben und fertig - da der oben beschriebenen Methode können Sie beliebig große Mengen von zahlen (und Daten) erfordern keine Erstellung der Tabelle, das wäre schmerzhaft, hart-code in der Art und Weise, die Sie vorschlagen. Natürlich für 5 Termine es ist übertrieben; aber selbst dann, wenn Sie sich gegen einen Tisch, wo Sie nicht wissen, die Termine im Voraus, sondern nur das mögliche min-und max-Werten, macht es Sinn.
Es ist wirklich schön zu sehen, eine Antwort auf die Frage, keine endlosen Kommentare, wie kann es nicht, oder sollte nicht getan werden. Die meisten Dinge, die getan werden kann, und "sollte" ist nur sinnvoll im Kontext, unterscheidet sich für jedermann. Diese Antwort hat mir geholfen, obwohl ich bin mir wohl bewusst, dass es bessere Wege in den meisten Situationen.
Diejenigen von Euch, die nicht bekommen kann diese Abfrage arbeiten: Bitte Schlag dich ins Gesicht, und dann wieder Lesen die OP ' s Kommentar zu dieser Abfrage zu generieren 1000 Termine. Seit 2010 war mehr als 1000 Tage her ist, müssen Sie passen Sie die Abfrage entsprechend.
InformationsquelleAutor RedFilter
Hier ist eine weitere Variante unter Verwendung von sichten:
Dann können Sie einfach tun (sehen Sie, wie elegant es ist?):
Update
Es ist erwähnenswert, dass Sie nur in der Lage sein zu generieren vergangene Termine ab dem aktuellen Datum. Wenn Sie wollen, zu generieren jede Art von Daten-Bereich (Vergangenheit, Zukunft, und dazwischen), müssen Sie diese Ansicht verwenden, stattdessen:
Gute Entscheidung, @user927258. Dies ist, weil der erste Blick
dates
oben erwähnt berechnet die Daten ab dem aktuellen Datum, das ist, warum Sie nicht in der Lage zum abrufen von Datumsangaben in der Zukunft. Antwort von @RedFilter leidet unter dem gleichen entwurfsfehler. Ich habe soeben einen workaround in meiner Antwort obwohl.Funktioniert sehr gut
Mit einigen Ansichten definitiv vereinfacht das Abfragen, und macht Sie wiederverwendbar. Obwohl Sie im wesentlichen die gleiche Sache zu tun, alle diese
UNION
Klauseln seltsam Aussehen in einem einzigen SQL-Anweisung.InformationsquelleAutor Stéphane
Akzeptierte Antwort hat nicht funktioniert für PostgreSQL (syntax-Fehler an oder in der Nähe von "einen").
Die Art und Weise Sie dies tun, in PostgreSQL, ist die Verwendung
generate_series
- Funktion, D. H.:InformationsquelleAutor Dmitry Gusev
Mithilfe einer rekursiven Common Table Expression (CTE), Sie erstellen eine Liste mit Daten, dann wählen Sie es aus. Natürlich werden Sie normalerweise würde nicht wollen, zu erstellen, die drei Millionen Daten, also das zeigt einfach die Möglichkeiten. Sie konnte einfach begrenzen den Datumsbereich innerhalb der CTE und weglassen der where-Klausel von der select-Anweisung mithilfe der CTE.
Auf Microsoft SQL Server 2005, die Erzeugung des CTE-Liste aller möglichen Termin dauerte 1:08. Generierung von ein hundert Jahre dauerte weniger als eine Sekunde.
InformationsquelleAutor Joshua
MSSQL Abfrage
Ausgabe
InformationsquelleAutor SUHAIL AG
Dem old-school-Lösung, dies zu tun, ohne eine Schleife/cursor zum erstellen einer
NUMBERS
Tabelle, die eine Spalte mit einzelnen ganzen zahlen Werte bei 1 beginnend.Müssen Sie füllen Sie die Tabelle mit genügend Datensätze, um Ihre Bedürfnisse abdecken:
Sobald Sie die
NUMBERS
Tabelle, die Sie verwenden können:Den absoluten low-tech-Lösung wäre:
Was würden Sie verwenden?
Generieren, Listen mit Daten oder zahlen, um die LINKE Ecke. Würden Sie dies, um zu sehen, wo es Lücken in den Daten, weil Sie LINKE sind, den Beitritt auf eine Liste von sequencial Daten - null-Werte wird es klar, wo die Lücken vorhanden sind.
dual
?Die
DUAL
Tabelle wird unterstützt von Oracle und MySQL zu verwenden als stand-in der Tabelle in derFROM
- Klausel. Es existiert nicht, durch die Auswahl von Werten aus es zurück was auch immer das Wert ist. Die Idee war, das stand-in, weil einer SELECT-Abfrage erfordert eineFROM
- Klausel die Angabe mindestens einer Tabelle.+1 für die Errichtung eines ständigen zahlen-Tabelle anstatt die RDBMS-bauen Sie es mit jedem mal müssen Sie die Abfrage. Hilfs-Tabellen sind nicht böse, Leute!
InformationsquelleAutor OMG Ponies
Für Access 2010 - mehrere Schritte erforderlich; ich folgte dem gleichen Muster wie oben gepostet, aber dachte, ich könnte helfen, jemand in Access. Funktionierte großartig für mich, ich habe nicht zu halten ausgesät Tabelle von Daten.
Erstellen Sie eine Tabelle namens DUAL (ähnlich wie die Oracle-DUAL-Tabelle funktioniert)
Erstellen Sie eine Abfrage mit dem Namen "ZeroThru9Q"; geben Sie manuell die folgende syntax:
Erstellen Sie eine Abfrage mit dem Namen "TodayMinus1KQ" (für Termine vor heute); manuell geben Sie die folgende syntax:
Erstellen Sie eine Abfrage mit dem Namen "TodayPlus1KQ" (für Termine nach heute); manuell geben Sie die folgende syntax:
Erstellen einer union-Abfrage namens "TodayPlusMinus1KQ" (für Daten +/- 1000 Tage):
Nun können Sie die Abfrage:
InformationsquelleAutor Travis
thx Pentium10 Sie, mich zu begleiten stackoverflow 🙂 -
dies ist meine Portierung zu msaccess - denke, es werde auf keiner version:
verwiesen MSysObjects nur, weil access die Tabelle countin' mindestens 1-Datensatz, die in einer from-Klausel - jede Tabelle mit mindestens 1 Eintrag tun würde.
InformationsquelleAutor user3780177
Verfahren + temporäre Tabelle:
InformationsquelleAutor Márcio Souza Júnior
versuchen.
InformationsquelleAutor loalexzzzz
wenn Sie jemals brauchen mehr als ein paar Tage, müssen Sie eine Tabelle.
Erstellen Sie einen Datumsbereich in mysql
dann,
InformationsquelleAutor gcb
Wie gesagt (oder zumindest angedeutet) in den vielen wundervollen Antworten bereits gegeben, dieses problem ist leicht gelöst werden, sobald Sie haben eine Reihe von zahlen, mit zu arbeiten.
Hinweis: Das folgende T-SQL, aber es ist einfach meine insbesondere die Umsetzung allgemeiner Konzepte, die bereits hier erwähnt und auf das internet im Allgemeinen. Es sollte relativ einfach zu konvertieren Sie den code zu Ihrem Dialekt Wahl.
Wie? Betrachten Sie diese-Abfrage:
Den oben erzeugt den Datumsbereich 1/22/0001 - 1/27/0001 und ist extrem trivial. Es gibt 2 wichtige Informationen in der oben genannten Abfrage: die Startdatum von
0001-01-22
und die offset von5
. Wenn wir kombinieren diese zwei Stücke von Informationen, die wir offensichtlich haben unsere end-Datum. So, da zwei Termine, die Erzeugung einer Reihe aufgeteilt werden kann, etwa so:Finden Sie die Differenz zwischen zwei angegebenen Datumsangaben (offset), das ist einfach:
-- Returns 125
SELECT ABS(DATEDIFF(d, '2014-08-22', '2014-12-25'))
Mit
ABS()
hier wird sichergestellt, dass die Datum-Reihenfolge ist irrelevant.Generieren eine begrenzte Anzahl von zahlen, die auch einfach:
-- Returns the numbers 0-2
SELECT N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1
FROM(SELECT 'A' AS S UNION ALL SELECT 'A' UNION ALL SELECT 'A')
Bemerken wir nicht eigentlich egal, was wir auswählen
FROM
hier. Wir brauchen nur einen Satz, um mit zu arbeiten, so dass wir die Anzahl der Zeilen in es. Ich persönlich benutze ein TVF, manche verwenden eine CTE, andere verwenden eine zahlen-Tabelle statt, Sie erhalten die Idee. Ich trete für die meisten performante Lösung, die Sie auch verstehen.Die Kombination dieser zwei Methoden wird die Lösung für unser problem:
Obigen Beispiel ist der schreckliche code, der aber zeigt, wie alles zusammen kommt.
Mehr Spaß
Ich brauche zu tun diese Art der Sache so viel ich lockerte die Logik in zwei TVFs. Die erste generiert eine Reihe von zahlen, und die zweite nutzt diese Funktion generiert eine Reihe von Daten. Die Mathematik ist zu gewährleisten, dass der input ist die Reihenfolge egal und da wollte ich die gesamte Palette der verfügbaren Nummern in
GenerateRangeSmallInt
.Die folgende Funktion nimmt ~16ms von CPU-Zeit, um die Auswahl von maximal 65536 Termine.
InformationsquelleAutor Kittoes0124
Generieren von Daten zwischen zwei Datums-Felder
, Wenn man sich mit SQL-CTE-Abfrage, dann wird diese Lösung hilft, Sie zu lösen Ihre Frage
Hier ist Beispiel
Wir haben die Termine in einer Tabelle
Tabelle-Name: ""datumtest""
Erforderlich Ergebnis:
Lösung:
Erklärung: CTE Rekursive Abfrage Erklärung
Ersten Teil der Abfrage ein:
SELECT DISTINCT convert(varchar(10), StartTime, 101) AS StartTime, datediff(dd, StartTime, endTime) AS diff FROM dbo.testdate
Erklärung: firstcolumn "startdate", die zweite Spalte ist die Differenz von start-und end -
Datum in Tage und es wird prüfen, wie der "diff" - Spalte
Zweite Teil der Abfrage:
UNION ALL SELECT StartTime, diff-1 AS diff FROM CTE WHERE diff<>0
Erklärung: Union alle Erben Ergebnis der obigen Abfrage, bis das Ergebnis null geht,
So "StartTime" führt Erben aus den generierten CTE-Abfrage, und von diff -, Abnahme - 1, so seine sieht aus wie 3, 2, und 1 bis 0
Beispielsweise
Ergebnis Spezifikation
3. Teil des Query
SELECT DISTINCT DateAdd(dd,diff, StartTime) AS StartTime FROM CTE
Es wird Tag "diff" in "startdate", so das Ergebnis sollte, wie unten
Ergebnis
InformationsquelleAutor Tarun Harkinia
Kürzer als akzeptierte Antwort, gleiche Idee:
InformationsquelleAutor daniherculano
Für jeden, der will dies als Ansicht gespeichert werden (MySQL unterstützt keine geschachtelten select-Anweisungen, Ansichten):
Können Sie dann tun
bekommen
InformationsquelleAutor Tom G
Es ist eine gute Idee mit dem erzeugen dieser Daten on-the-fly. Aber ich fühle mich nicht bequem, dies zu tun mit einer ziemlich großen range also ich habe endete mit der folgenden Lösung:
CREATE TABLE DatesNumbers (
i MEDIUMINT NOT NULL,
PRIMARY KEY (i)
)
COMMENT='Used by Dates view'
;
INSERT INTO DatesNumbers
SELECT
a.i + (10 * b.i) + (100 * c.i) + (1000 * d.i) + (10000 * e.i) - 59999 AS i
FROM
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS a
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS b
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS c
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS d
(SELECT 0 AS i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) AS e
;
SELECT
i
, CURRENT_DATE() + INTERVAL i DAY AS Date
FROM
DatesNumbers
Das ist es.
WHERE i < 0
oderWHERE i > 0
(PK)InformationsquelleAutor fifonik
Sie möchten, zu bekommen, die einen Datumsbereich.
In Ihrem Beispiel, das Sie möchten, um die Daten zwischen '2010-01-20' und '2010-01-24'
mögliche Lösung:
Erklärung
MySQL hat eine date_add - Funktion, so
geben Sie
Den datediff Funktion würde Sie wissen lassen, oft müssten Sie wiederholen Sie diesen
gibt
Abrufen einer Liste von Daten in einem Datumsbereich läuft darauf hinaus, die Erstellung einer Sequenz von integer-zahlen sehen generiert eine integer-Sequenz in MySQL
Die meisten von Ihnen positiv bewertet werden die Antwort hier genommen hat, einen ähnlichen Ansatz wie https://stackoverflow.com/a/2652051/1497139 als Grundlage:
führen
Den Zeilen kann nun verwendet werden, um erstellen Sie eine Liste der Termine ab dem angegebenen Datum beginnen. Enthalten die start-Zeitpunkt beginnen wir mit der Zeile -1;
InformationsquelleAutor Wolfgang Fahl
Okay.. Versuchen Sie dies:
http://www.devshed.com/c/a/MySQL/Delving-Deeper-into-MySQL-50/
http://dev.mysql.com/doc/refman/5.0/en/loop-statement.html
http://www.roseindia.net/sql/mysql-example/mysql-loop.shtml
Verwenden, dass um, sagen wir, erstellen Sie eine temporäre Tabelle, und führen Sie dann einen select * auf die temp-Tabelle. Oder die Ausgabe der Ergebnisse ein zu einer Zeit.
, Was Sie sagen, Sie wollen zu tun, nicht getan werden kann mit einer SELECT-Anweisung, aber es könnte machbar sein mit Dingen, die spezifisch für MySQL.
Dann wieder, vielleicht brauchen Sie Cursor: http://dev.mysql.com/doc/refman/5.0/en/cursors.html
Loop
klingt interessantInformationsquelleAutor Trevoke
For Oracle ist meine Lösung:
DATEPART verändert werden kann, um bestimmte Datum und die Nummer für die Ebene geändert werden können, geben weitere Termine.
InformationsquelleAutor mousetwentytwo
wenn Sie möchten, dass die Liste der Termine zwischen zwei Terminen:
*Geigen hier: http://sqlfiddle.com/#!6/9eecb/3469
InformationsquelleAutor celerno
InformationsquelleAutor Benigno Geronimo
InformationsquelleAutor Victor Silva
SQLite version von RedFilters top-Lösung
InformationsquelleAutor martin
verbessert mit Wochentag eine Beitritt zu einer custom-Urlaub-Tabelle
microsoft MSSQL 2012 für die powerpivot-Datum-Tabelle
https://gist.github.com/josy1024/cb1487d66d9e0ccbd420bc4a23b6e90e
InformationsquelleAutor josy1024
Eine weitere Lösung für mysql-8.0.1-und mariadb 10.2.2 Verwendung von rekursiven common table expressions:
InformationsquelleAutor Слаффка Островский
InformationsquelleAutor Norbert Madarász
Elegante Lösung mit neuen rekursive (Common Table Expressions) - Funktionalität in MariaDB >= 10.3 und MySQL >= 8.0.
Den oben genannten gibt eine Tabelle von Daten, die zwischen '2019-01-01' und '2019-04-30'. Es ist auch anständig schnell. Rückkehr 1000 Jahre im Wert von Daten (~365,000 Tage) dauert etwa 400ms auf meinem Rechner.
InformationsquelleAutor Brad
Können eine Prozedur erstellen auch das erstellen Kalender Tabelle mit timestmap anders Tag.
Wenn Sie möchten, eine Tabelle für jedes Quartal
z.B.
können Sie
und dann manipulieren durch
geben, dass Sie auch ts
von hier aus können Sie beginnen, hinzufügen von anderen Informationen, wie
erstellen oder eine echte Tabelle mit create table-Anweisung
InformationsquelleAutor Gianluca D'Ardia