【问题标题】:SELECT any FROM system从系统中选择任何
【发布时间】:2011-01-18 21:23:50
【问题描述】:

这些查询中的任何一个都可以在 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,这就是我要问的原因。

【问题讨论】:

  • 不清楚你在问什么。你有什么问题?您是在问是否可以查询所有数据库中的所有表,还是在问是否可以查询名为“system”的表?第二个示例应该可以正常工作。第一个示例不会像您想象的那样工作,那是两段文本,而不是日期。您需要以正确的格式存储日期。
  • 我认为它们的意思是简单的查询,以便即时获取给定范围内的日期或数字列表。
  • @Tom:我猜他要的是generate_series
  • 你使用的是什么 dbms?
  • 你为什么要在数据库中这样做?这似乎是逻辑层应该做的事情。

标签: sql ansi-sql


【解决方案1】:

我假设您希望根据系列中的第一个和最后一个值生成任意数量的值的记录集。

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
  • MYSQL: SELECT num from (select @num:=@num+1 as num from big_table, (select @num:=10) num) as q WHERE num&lt;=19 (stackoverflow.com/a/6871220/2115135)
  • @JakubKania:你需要先拥有big_table
  • @Quassnoi 你需要有至少两行的任何表,你可以从那里交叉连接。拥有big_table 不是问题,问题是如果记录集太大,您可能需要另一个交叉连接。
  • @JakubKania:您可能没有对数据库的写入权限,因为这种情况通常发生在报表开发人员身上。在这种情况下,您可以使用(SELECT 1 UNION ALL SELECT 2 …) q,但确切的查询布局将取决于您想要的记录数。我很清楚解决方法,问题不在于它们。
【解决方案2】:

日期的排序... SQL 团队的 Michael Valentine Jones 有一个很棒的日期函数

在这里查看:

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

【讨论】:

    【解决方案3】:

    在甲骨文中

    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
    )
    

    【讨论】:

      【解决方案4】:

      如果你想得到天的列表,用类似的 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 秒内运行。

      顺便说一句,这是一种非常便携的技术,只需稍作调整即可与大多数数据库一起使用。

      【讨论】:

      【解决方案5】:

      不确定这是否是您要问的,但如果您想从表格中选择一些东西,您可以使用“DUAL”

      select 1, 2, 3 from dual;
      

      将返回一行 3 列,包含这三个数字。

      从 dual 中选择对于运行函数很有用。可以通过手动输入运行函数,而不是在其中选择其他内容。例如:

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

      将返回 some_func 的结果。

      【讨论】:

        【解决方案6】:

        在 SQL Server 中,您可以使用 BETWEEN 关键字。

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

        【讨论】:

        • 除了 where 子句之外还能使用吗?或者,除了从表中选择之外,还可以使用 where 子句吗?
        • 只需要记住 BETWEEN 包含边界,而 OP 的示例不包括边界。
        【解决方案7】:

        您可以使用WHEREAND WHERE 选择范围。我无法谈论性能,但有可能。

        【讨论】:

        • 你可以。但是在从表或视图中选择时,必须使用 AFAIK,WHERE。问题似乎是在询问如何生成日期或数字,即不是来自已填充的表或视图。
        【解决方案8】:

        解决此问题的最简单方法是使用 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 

        一旦您填充了该表,除非您想扩展它,否则您永远不需要触摸它。我将日期和数字合并到一个表中,但如果您需要的数字多于日期,则可以将其分成两个表。此外,我随意用 100K 行填充了表格,但您显然可以添加更多。 1900-01-01 到 9999-12-31 之间的每一天大约需要 434K 行。您可能不需要那么多,但即使您需要,存储空间也很小。

        无论如何,这是解决许多间隙和序列问题的常用技术。例如,您的原始查询全部在不到十分之一秒内运行。您还可以使用这种表格来解决差距问题,例如:

        选择数值
        来自 dbo.Tally
            左加入 MyTable
                在 Tally.NumericValue = MyTable.IdentityColumn
        SomeLowValue 和 SomeHighValue 之间的 Tally.NumericValue 位置
        

        【讨论】:

          猜你喜欢
          • 2016-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多