2010-02-19 12 views
5

Kann eine dieser Abfragen in SQL durchgeführt werden?SELECT Beliebige FROM-System

SELECT dates FROM system 
WHERE dates > 'January 5, 2010' AND dates < 'January 30, 2010' 

SELECT number FROM system 
WHERE number > 10 AND number < 20 

Ich möchte eine generate_series schaffen, und das ist, warum ich frage.

+4

Es ist nicht klar, was Sie fragen. Was ist das Problem, das du hast? Fragen Sie, ob Sie alle Tabellen in allen Datenbanken abfragen können oder fragen Sie, ob Sie eine Tabelle namens "system" abfragen können? Das zweite Beispiel sollte gut funktionieren. Das erste Beispiel funktioniert nicht wie du denkst, das sind zwei Textabschnitte, keine Daten. Sie müssen Daten in einem geeigneten Format speichern. – Tom

+1

Ich denke, dass sie einfache Abfragen bedeuten, um Listen von Daten oder Zahlen zwischen vorgegebenen Bereichen zu erhalten. – MartW

+2

@Tom: Ich nehme an, er fragt nach 'generate_series'. – Quassnoi

Antwort

12

Ich nehme an, Sie möchten ein Recordset einer beliebigen Anzahl von Werten basierend auf dem ersten und letzten Wert in der Serie generieren.

In PostgreSQL:

SELECT num 
FROM generate_series (11, 19) num 

In SQL Server:

WITH q (num) AS 
     (
     SELECT 11 
     UNION ALL 
     SELECT num + 1 
     FROM q 
     WHERE num < 19 
     ) 
SELECT num 
FROM q 
OPTION (MAXRECURSION 0) 

In Oracle:

SELECT level + 10 AS num 
FROM dual 
CONNECT BY 
     level < 10 

In MySQL:

Entschuldigung.

+0

ah. du schlägst mich dazu ... sehr nette Antwort +1 – EvilTeach

+0

MYSQL: 'SELECT num von (wähle @num: = @ num + 1 als num von big_table, (wähle @num: = 10) num) als q WHERE num <= 19' (http://Stackoverflow.com/a/6871220/2115135) –

+0

@JakubKania: Sie müssen zuerst 'big_table' haben. – Quassnoi

0

Nicht sicher, ob das, was Sie ist Fragen, aber wenn Sie etwas nicht aus einer Tabelle auswählen möchten, können Sie "DUAL"

select 1, 2, 3 from dual; 
verwenden

gibt eine Zeile mit 3 Spalten zurück, die diese drei Ziffern enthalten.

Die Auswahl von dual ist nützlich für die Ausführung von Funktionen. Eine Funktion kann mit manueller Eingabe ausgeführt werden, anstatt etwas anderes auszuwählen. Zum Beispiel:

select some_func('First Parameter', 'Second parameter') from dual; 

wird die Ergebnisse von some_func zurückgeben.

0

In SQL Server können Sie das Schlüsselwort BETWEEN verwenden.

-Link: http://msdn.microsoft.com/nl-be/library/ms187922(en-us).aspx

+0

Kann dies anders als in einer Where-Klausel verwendet werden? Oder kann eine WHERE-Klausel anders als die Auswahl aus einer Tabelle verwendet werden? –

+0

Man muss sich nur daran erinnern, dass BETWEEN die Grenzen einschließt, während das Beispiel des OP sie ausschließt. – DyingCactus

0

Sie können einen Bereich auswählen, indem WHERE und AND WHERE verwenden. Ich kann nicht mit der Leistung sprechen, aber es ist möglich.

+0

Sie können. Aber AFAIK, 'WHERE' muss verwendet werden, wenn aus einer Tabelle oder Ansicht ausgewählt wird. Die Frage scheint zu fragen, wie man Daten oder Zahlen erzeugt, dh NICHT aus einer Tabelle oder einer Ansicht, die bereits gefüllt ist. –

+0

Was ist "UND WO"? –

1

In Oracle

WITH 
START_DATE AS 
(
    SELECT TO_CHAR(TO_DATE('JANUARY 5 2010','MONTH DD YYYY'),'J') 
    JULIAN FROM DUAL 
), 
END_DATE AS 
(
    SELECT TO_CHAR(TO_DATE('JANUARY 30 2010','MONTH DD YYYY'),'J') 
    JULIAN FROM DUAL 
), 
DAYS AS 
(
    SELECT END_DATE.JULIAN - START_DATE.JULIAN DIFF 
    FROM START_DATE, END_DATE 
) 
SELECT TO_CHAR(TO_DATE(N + START_DATE.JULIAN, 'J'), 'MONTH DD YYYY') 
     DESIRED_DATES 
FROM 
START_DATE, 
(
    SELECT LEVEL N 
    FROM DUAL, DAYS 
    CONNECT BY LEVEL < DAYS.DIFF 
) 
1

Wenn Sie die Liste der Tage zu bekommen, mit einem SQL wie

wählen ...als Tage, wo date zwischen ‚2010-01-20‘ und ‚2010-01-24‘

Und geben Daten wie ist:

days 
---------- 
2010-01-20 
2010-01-21 
2010-01-22 
2010-01-23 
2010-01-24 

Diese Lösung verwendet keine Schleifen, Prozeduren oder temporäre Tabellen. Die Unterabfrage generiert Daten für die letzten tausend Tage und kann so erweitert werden, dass sie so weit zurück oder vorwärts gehen, wie Sie möchten.

select a.Date 
from (
    select curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY as Date 
    from (select 0 as a 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 
    cross join (select 0 as a 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 
    cross join (select 0 as a 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 
) a 
where a.Date between '2010-01-20' and '2010-01-24' 

Ausgang:

Date 
---------- 
2010-01-24 
2010-01-23 
2010-01-22 
2010-01-21 
2010-01-20 

Hinweise zur Leistung

Testen Sie es aus here, ist die Leistung überraschend gut: Die obige Abfrage dauert 0,0009 Sekunden.

Wenn wir die Unterabfrage erweitern, um ca. 100.000 Zahlen (und damit etwa 274 Jahre Daten), läuft es in 0,0458 Sekunden.

Übrigens ist dies eine sehr portable Technik, die mit den meisten Datenbanken mit kleinen Anpassungen funktioniert.

+0

Ich würde lieber MVJ DATE FUNCTION verwenden, es ist viel flexibler und die Leistung ist fantastisch. http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519 – JonH

+0

Das ist nicht in MySQL noch in Postgresql und SQLite verfügbar – Pentium10

0

Die einfachste Lösung für dieses Problem ist eine Tally- oder Numbers-Tabelle. Das ist eine Tabelle, die einfach eine Folge von ganzen Zahlen speichert und/oder Daten

Create Table dbo.Tally ( 
         NumericValue int not null Primary Key Clustered 
         , DateValue datetime NOT NULL 
         , Constraint UK_Tally_DateValue Unique (DateValue) 
         ) 
GO 

;With TallyItems 
As (
    Select 0 As Num 
    Union All 
    Select ROW_NUMBER() OVER (Order By C1.object_id) As Num 
    From sys.columns as c1 
     cross join sys.columns as c2 
    ) 
Insert dbo.Tally(NumericValue, DateValue) 
Select Num, DateAdd(d, Num, '19000101') 
From TallyItems 
Where Num

Sobald Sie die Tabelle gefüllt haben, müssen Sie es nie berühren, wenn Sie es erweitern möchten. Ich kombinierte die Daten und Zahlen in einer einzigen Tabelle, aber wenn Sie mehr Zahlen als Daten brauchten, dann könnten Sie es in zwei Tabellen brechen. Zusätzlich habe ich die Tabelle willkürlich mit 100K Zeilen gefüllt, aber Sie könnten natürlich mehr hinzufügen. Jeder Tag zwischen 1900-01-01 bis 9999-12-31 dauert etwa 434K Reihen. Sie werden wahrscheinlich nicht so viele brauchen, aber selbst wenn, dann ist der Speicher winzig.

Unabhängig davon ist dies eine gängige Technik zur Lösung vieler Lücken und Sequenzen Probleme. Zum Beispiel liefen Ihre ursprünglichen Abfragen alle in weniger als einer Zehntelsekunde. Sie können auch diese Art von Tabelle verwenden, um Lücken Probleme wie zu lösen:

Select NumericValue 
From dbo.Tally 
    Left Join MyTable 
     On Tally.NumericValue = MyTable.IdentityColumn 
Where Tally.NumericValue Between SomeLowValue And SomeHighValue