可以在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
,这就是我要问的原因。
答案 0 :(得分: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
:
对不起。
答案 1 :(得分:1)
日期排序...... SQL Team的Michael Valentine Jones有一个很棒的日期函数
在这里查看:
答案 2 :(得分:1)
在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
)
答案 3 :(得分:1)
如果您想获取日期列表,请使用类似
的SQL选择... date
介于'2010-01-20'和'2010-01-24'之间的日期
并返回如下数据:
days
----------
2010-01-20
2010-01-21
2010-01-22
2010-01-23
2010-01-24
此解决方案不使用循环,过程或临时表。子查询生成过去千日的日期,并且可以根据需要延伸到后退或前进。
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
绩效说明
测试它here,性能出乎意料地好:上面的查询需要0.0009秒。
如果我们扩展子查询以生成约。 100,000个数字(因此约为274年的日期),它的运行时间为0.0458秒。
顺便提一下,这是一种非常便携的技术,可以对大多数数据库进行微调。
答案 4 :(得分:0)
不确定这是否是您所要求的,但如果您想要选择不是来自桌子的东西,可以使用'DUAL'
select 1, 2, 3 from dual;
将返回一个包含3列的行,包含这三个数字。
从dual中选择对于运行函数很有用。可以使用手动输入运行功能,而不是在其中选择其他内容。例如:
select some_func('First Parameter', 'Second parameter') from dual;
将返回some_func的结果。
答案 5 :(得分:0)
在SQL Server中,您可以使用BETWEEN
关键字。
链接: http://msdn.microsoft.com/nl-be/library/ms187922(en-us).aspx
答案 6 :(得分:0)
您可以使用WHERE
和AND WHERE
选择范围。我不能说性能,但它可能。
答案 7 :(得分: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