【问题标题】:How can I read the first n rows of table a based upon the number of rows in table b?如何根据表 b 中的行数读取表 a 的前 n 行?
【发布时间】:2020-07-04 18:04:24
【问题描述】:

我有一个表“L20”,其中包含 1 到 20 个值“HDIF”,按升序排序。我需要根据表“L20”中值的数量将这些值的前 1 到 10 个提取到表“T10”中。我正在使用带有 Firebird 3 数据库的 Windows 10、Libreoffice 6.4.4。我已经在“L20”中的 COUNT 行上尝试了 CASE 语句和 DECODE 语句,但似乎都不起作用。

如果我在表“L20”上为 SELECT 输入一个数字,那么它可以正常工作。任何人都知道如何解决?此查询的目的是计算一个高尔夫让分盘,它使用 [最多] 最近(最近)20 场比赛的最佳(最低)10 分。下面是代码:


/* Qry_Index_Calc - calculates handicap index from top 10 differentials of last 20 games  */
/* Source is "VW_Plyr_Diff" which has handicap differentials already calculated. */

SELECT (AVG ("T10"."HDIF") * .96) "Index", (Count ("T10"."HDIF")) FROM

/* Get only the games needed if less than 20 games have been played. */

    (
    SELECT FIRST 

        DECODE ((SELECT COUNT (*) FROM "L20"), 
              1,  1
            , 2,  1
            , 3,  1
            , 4,  1
            , 5,  1
            , 6,  1     
            , 7,  2
            , 8,  2
            , 9,  3
            , 10, 3
            , 11, 4
            , 12, 4
            , 13, 5
            , 14, 5
            , 15, 6
            , 16, 6
            , 17, 7
            , 18, 8
            , 19, 9
            , 10)

    "L20"."HDIF"

    FROM

/*  Get up to 20 of the most recent (last) games played.  */

            ( SELECT FIRST 20 "PlayerID" "PID", "GID" "GID", 
            RANK ( ) OVER ( PARTITION BY "PlayerID" ORDER BY "Diff" ) "Rnk", 
            "Diff" "HDIF", "Date" "Gdate"
            FROM "Vw_Plyr_Diff"
            WHERE "PlayerID" = 1) 

            "L20"   

    ) "T10"

【问题讨论】:

    标签: sql select firebird firebird-3.0 libreoffice-base


    【解决方案1】:

    您需要在FIRST 中的表达式周围加上括号。如Firebird 3.0 Language Reference for FIRST, SKIP中指定:

    SELECT
      [FIRST <m>] [SKIP <n>]
      FROM ...
      ...
    
    <m>, <n>  ::=
        <integer-literal>
      | <query-parameter>
      | (<integer-expression>)
    

    所以,使用

    select first (decode(...)) ....
    

    first中直接使用子查询时,需要使用双括号(一次用于表达式,一次用于表达式中的子查询用括号括起来。

    Firebird 3 中引入的 SQL 标准 OFFSET/FETCH 子句不支持表达式。

    请注意,您当前的代码没有指定ORDER BY,这意味着未定义确切返回哪些行,这将取决于数据库中数据的位置、访问计划等。我建议您添加适当的ORDER BY 子句以确保返回的行符合预期。

    您似乎正在尝试从FROM 子句中定义的派生表L20 中进行SELECT,而不是从实际表L20 中。如果您希望能够做到这一点,那么L20 最多可以指定为common table expression

    【讨论】:

    • 马克,明白了!谢谢!我错过了括号问题,没有意识到 CTE 是什么,或者它可以做什么。这是我第一次尝试 SQL,我为此苦苦挣扎了一段时间。现在它已经解决了,我可以继续开发应用程序。再次感谢。
    • @BruceReirden 不客气。如果我的回答对您有帮助,请点击复选标记接受答案。
    猜你喜欢
    • 1970-01-01
    • 2015-08-04
    • 2013-11-10
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 2018-10-01
    相关资源
    最近更新 更多