6

これらのクエリのいずれかを SQL で実行できますか?

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

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

を作成したいgenerate_seriesのですが、それが私が尋ねている理由です。

4

8 に答える 8

12

シリーズの最初と最後の値に基づいて、任意の数の値のレコードセットを生成したいとします。

PostgreSQL

SELECT  num
FROM    generate_series (11, 19) num

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)

Oracle

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

MySQL

ごめん。

于 2010-02-19T17:31:12.843 に答える
1

オラクルでは

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
)
于 2010-02-19T18:07:13.540 に答える
1

日付のソート... SQLチームのMichael Valentine Jonesには素晴らしい日付関数があります

ここでチェックしてください:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=61519

于 2010-02-19T17:31:21.350 に答える
1

日のリストを取得したい場合は、次のようなSQLを使用します

select ... date'2010-01-20' と '2010-01-24' の間の日として

そして、次のようなデータを返します。

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

このソリューションでは、ループ、プロシージャ、または一時テーブルは使用されません。サブクエリは過去 1,000 日間の日付を生成し、必要に応じて前後に拡張できます。

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' 

出力:

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

性能上の注意

ここでテストすると、パフォーマンスは驚くほど良好です。上記のクエリは 0.0009 秒かかります。

サブクエリを拡張して約を生成するとします。100,000 の数値 (したがって、約 274 年分の日付) を 0.0458 秒で実行します。

ちなみに、これは非常に移植性の高い手法であり、ほとんどのデータベースでわずかな調整を加えるだけで機能します。

于 2010-02-19T18:50:38.243 に答える
0

これがあなたが求めているものかどうかはわかりませんが、テーブル以外のものを選択したい場合は、「DUAL」を使用できます

select 1, 2, 3 from dual;

これらの 3 桁を含む 3 列の行を返します。

デュアルから選択すると、機能を実行するのに役立ちます。関数は、何か他のものを選択する代わりに、手動入力で実行できます。例えば:

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

some_func の結果を返します。

于 2010-02-19T17:34:31.410 に答える
0

BETWEENSQL Server では、キーワードを使用できます。

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

于 2010-02-19T17:35:32.373 に答える
0

WHEREと を使用して範囲を選択できますAND WHERE。パフォーマンスについて話すことはできませんが、可能です。

于 2010-02-19T17:38:54.873 に答える
0

この問題の最も簡単な解決策は、Tally または Numbers テーブルです。これは、一連の整数および/または日付を単純に格納するテーブルです

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 

Once you have that table populated, you never need touch it unless you want to expand it. I combined the dates and numbers into a single table but if you needed more numbers than dates, then you could break it into two tables. In addition, I arbitrarily filled the table with 100K rows but you could obviously add more. Every day between 1900-01-01 to 9999-12-31 takes about 434K rows. You probably won't need that many but even if you did, the storage is tiny.

Regardless, this is a common technique to solving many gaps and sequences problems. For example, your original queries all ran in less than tenth of a second. You can also use this sort of table to solve gaps problems like:

Select NumericValue
From dbo.Tally
    Left Join MyTable
        On Tally.NumericValue = MyTable.IdentityColumn
Where Tally.NumericValue Between SomeLowValue And SomeHighValue
于 2010-02-20T07:17:31.530 に答える