带有 FIRST 选项的 Informix 子查询

发布于 2024-07-25 02:07:36 字数 307 浏览 8 评论 0原文

将以下 Transact-SQL 代码转录到 Informix Dynamic Server (IDS) 9.40 的最佳方法是什么:

目标:我需要前 50 个订单及其各自的订单行

select *
    from (select top 50 * from orders) a inner join lines b
            on a.idOrder = b.idOrder

我的问题在于子选择,因为 Informix 不允许使用 FIRST 选项子选择。

有什么简单的想法吗?

What is the best way of transcribing the following Transact-SQL code to Informix Dynamic Server (IDS) 9.40:

Objective: I need the first 50 orders with their respective order lines

select *
    from (select top 50 * from orders) a inner join lines b
            on a.idOrder = b.idOrder

My problem is with the subselect because Informix does not allow the FIRST option in the subselect.

Any simple idea?.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

单挑你×的.吻 2024-08-01 02:07:37

官方的回答是“请从 IDS 9.40 升级,因为 IBM 不再支持它”。 也就是说,IDS 9.40 不是当前版本 - 并且(理想情况下)不应使用。

IDS 11.50 的解决方案

使用 IDS 11.50,我可以写:

SELECT *
    FROM (SELECT FIRST 10 * FROM elements) AS e
         INNER JOIN compound_component AS a
            ON e.symbol = a.element
         INNER JOIN compound AS c
            ON c.compound_id = a.compound_id
    ;

这或多或少相当于您的查询。 因此,如果您使用当前版本的 IDS,则可以使用与 Transact-SQL 中几乎相同的表示法编写查询(使用 FIRST 代替 TOP)。

IDS 9.40 的解决方案

您可以在 IDS 9.40 中做什么? 打扰一下...我必须运行我的 IDS 9.40.xC7 服务器(此修复包于 2005 年发布;原始版本可能于 2003 年末)...

第一个问题 - IDS 9.40 不允许子查询在 FROM 子句中。

第二个问题 - IDS 9.40 不允许在以下任一上下文中使用“FIRST n”表示法:

SELECT FIRST 10 * FROM elements INTO TEMP e;
INSERT INTO e SELECT FIRST 10 * FROM elements;

第三个问题 - IDS 9.40 没有简单的 ROWNUM。

因此,为了解决这些问题,我们可以编写(使用临时表 - 我们稍后将删除它):

SELECT e1.*
    FROM elements AS e1, elements AS e2
    WHERE e1.atomic_number >= e2.atomic_number
    GROUP BY e1.atomic_number, e1.symbol, e1.name, e1.atomic_weight, e1.stable
    HAVING COUNT(*) <= 10
    INTO TEMP e;

SELECT *
    FROM e INNER JOIN compound_component AS a
                   ON e.symbol = a.element
           INNER JOIN compound AS c
                   ON c.compound_id = a.compound_id;

这会产生与 IDS 11.50 中的单个查询相同的答案。 我们可以避免使用临时表吗? 是的,但它更冗长:

SELECT e1.*, a.*, c.*
    FROM  elements AS e1, elements AS e2, compound_component AS a,
           compound AS c
    WHERE e1.atomic_number >= e2.atomic_number
      AND e1.symbol = a.element
      AND c.compound_id = a.compound_id
    GROUP BY e1.atomic_number, e1.symbol, e1.name, e1.atomic_weight,
             e1.stable, a.compound_id, a.element, a.seq_num,
             a.multiplicity, c.compound_id, c.name
    HAVING   COUNT(*) <= 10;

将其应用于原始订单和订单行示例留给读者作为练习。


“元素表”架构的相关子集:

-- See: http://www.webelements.com/ for elements.
-- See: http://ie.lbl.gov/education/isotopes.htm for isotopes.

CREATE TABLE elements
(
    atomic_number   INTEGER NOT NULL UNIQUE CONSTRAINT c1_elements
                    CHECK (atomic_number > 0 AND atomic_number < 120),
    symbol          CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
    name            CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
    atomic_weight   DECIMAL(8,4) NOT NULL,
    stable          CHAR(1) DEFAULT 'Y' NOT NULL
                    CHECK (stable IN ('Y', 'N'))
);

CREATE TABLE compound
(
    compound_id     SERIAL NOT NULL PRIMARY KEY,
    name            VARCHAR(100) NOT NULL UNIQUE
);

-- The sequence number is used to order the components within a compound.

CREATE TABLE compound_component
(
    compound_id     INTEGER REFERENCES compound,
    element         CHAR(3) NOT NULL REFERENCES elements(symbol),
    seq_num         SMALLINT DEFAULT 1 NOT NULL
                    CHECK (seq_num > 0 AND seq_num < 20),
    multiplicity    INTEGER NOT NULL
                    CHECK (multiplicity > 0 AND multiplicity < 20),
    PRIMARY KEY(compound_id, seq_num)
);

输出(在我的示例数据库上):

 1 H   Hydrogen        1.0079 Y     1 H    1     2       1 water
 1 H   Hydrogen        1.0079 Y     3 H    2     4       3 methane
 1 H   Hydrogen        1.0079 Y     4 H    2     6       4 ethane
 1 H   Hydrogen        1.0079 Y     5 H    2     8       5 propane
 1 H   Hydrogen        1.0079 Y     6 H    2    10       6 butane
 1 H   Hydrogen        1.0079 Y    11 H    2     5      11 ethanol
 1 H   Hydrogen        1.0079 Y    11 H    4     1      11 ethanol
 6 C   Carbon         12.0110 Y     2 C    1     1       2 carbon dioxide
 6 C   Carbon         12.0110 Y     3 C    1     1       3 methane
 6 C   Carbon         12.0110 Y     4 C    1     2       4 ethane
 6 C   Carbon         12.0110 Y     5 C    1     3       5 propane
 6 C   Carbon         12.0110 Y     6 C    1     4       6 butane
 6 C   Carbon         12.0110 Y     7 C    1     1       7 carbon monoxide
 6 C   Carbon         12.0110 Y     9 C    2     1       9 magnesium carbonate
 6 C   Carbon         12.0110 Y    10 C    2     1      10 sodium bicarbonate
 6 C   Carbon         12.0110 Y    11 C    1     2      11 ethanol
 8 O   Oxygen         15.9990 Y     1 O    2     1       1 water
 8 O   Oxygen         15.9990 Y     2 O    2     2       2 carbon dioxide
 8 O   Oxygen         15.9990 Y     7 O    2     1       7 carbon monoxide
 8 O   Oxygen         15.9990 Y     9 O    3     3       9 magnesium carbonate
 8 O   Oxygen         15.9990 Y    10 O    3     3      10 sodium bicarbonate
 8 O   Oxygen         15.9990 Y    11 O    3     1      11 ethanol

The official answer would be 'Please upgrade from IDS 9.40 since it is no longer supported by IBM'. That is, IDS 9.40 is not a current version - and should (ideally) not be used.

Solution for IDS 11.50

Using IDS 11.50, I can write:

SELECT *
    FROM (SELECT FIRST 10 * FROM elements) AS e
         INNER JOIN compound_component AS a
            ON e.symbol = a.element
         INNER JOIN compound AS c
            ON c.compound_id = a.compound_id
    ;

This is more or less equivalent to your query. Consequently, if you use a current version of IDS, you can write the query using almost the same notation as in Transact-SQL (using FIRST in place of TOP).

Solution for IDS 9.40

What can you do in IDS 9.40? Excuse me a moment...I have to run up my IDS 9.40.xC7 server (this fix pack was released in 2005; the original release was probably in late 2003)...

First problem - IDS 9.40 does not allow sub-queries in the FROM clause.

Second problem - IDS 9.40 does not allow 'FIRST n' notation in either of these contexts:

SELECT FIRST 10 * FROM elements INTO TEMP e;
INSERT INTO e SELECT FIRST 10 * FROM elements;

Third problem - IDS 9.40 doesn't have a simple ROWNUM.

So, to work around these, we can write (using a temporary table - we'll remove that later):

SELECT e1.*
    FROM elements AS e1, elements AS e2
    WHERE e1.atomic_number >= e2.atomic_number
    GROUP BY e1.atomic_number, e1.symbol, e1.name, e1.atomic_weight, e1.stable
    HAVING COUNT(*) <= 10
    INTO TEMP e;

SELECT *
    FROM e INNER JOIN compound_component AS a
                   ON e.symbol = a.element
           INNER JOIN compound AS c
                   ON c.compound_id = a.compound_id;

This produces the same answer as the single query in IDS 11.50. Can we avoid the temporary table? Yes, but it is more verbose:

SELECT e1.*, a.*, c.*
    FROM  elements AS e1, elements AS e2, compound_component AS a,
           compound AS c
    WHERE e1.atomic_number >= e2.atomic_number
      AND e1.symbol = a.element
      AND c.compound_id = a.compound_id
    GROUP BY e1.atomic_number, e1.symbol, e1.name, e1.atomic_weight,
             e1.stable, a.compound_id, a.element, a.seq_num,
             a.multiplicity, c.compound_id, c.name
    HAVING   COUNT(*) <= 10;

Applying that to the original orders plus order lines example is left as an exercise for the reader.


Relevant subset of schema for 'Table of Elements':

-- See: http://www.webelements.com/ for elements.
-- See: http://ie.lbl.gov/education/isotopes.htm for isotopes.

CREATE TABLE elements
(
    atomic_number   INTEGER NOT NULL UNIQUE CONSTRAINT c1_elements
                    CHECK (atomic_number > 0 AND atomic_number < 120),
    symbol          CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
    name            CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
    atomic_weight   DECIMAL(8,4) NOT NULL,
    stable          CHAR(1) DEFAULT 'Y' NOT NULL
                    CHECK (stable IN ('Y', 'N'))
);

CREATE TABLE compound
(
    compound_id     SERIAL NOT NULL PRIMARY KEY,
    name            VARCHAR(100) NOT NULL UNIQUE
);

-- The sequence number is used to order the components within a compound.

CREATE TABLE compound_component
(
    compound_id     INTEGER REFERENCES compound,
    element         CHAR(3) NOT NULL REFERENCES elements(symbol),
    seq_num         SMALLINT DEFAULT 1 NOT NULL
                    CHECK (seq_num > 0 AND seq_num < 20),
    multiplicity    INTEGER NOT NULL
                    CHECK (multiplicity > 0 AND multiplicity < 20),
    PRIMARY KEY(compound_id, seq_num)
);

Output (on my sample database):

 1 H   Hydrogen        1.0079 Y     1 H    1     2       1 water
 1 H   Hydrogen        1.0079 Y     3 H    2     4       3 methane
 1 H   Hydrogen        1.0079 Y     4 H    2     6       4 ethane
 1 H   Hydrogen        1.0079 Y     5 H    2     8       5 propane
 1 H   Hydrogen        1.0079 Y     6 H    2    10       6 butane
 1 H   Hydrogen        1.0079 Y    11 H    2     5      11 ethanol
 1 H   Hydrogen        1.0079 Y    11 H    4     1      11 ethanol
 6 C   Carbon         12.0110 Y     2 C    1     1       2 carbon dioxide
 6 C   Carbon         12.0110 Y     3 C    1     1       3 methane
 6 C   Carbon         12.0110 Y     4 C    1     2       4 ethane
 6 C   Carbon         12.0110 Y     5 C    1     3       5 propane
 6 C   Carbon         12.0110 Y     6 C    1     4       6 butane
 6 C   Carbon         12.0110 Y     7 C    1     1       7 carbon monoxide
 6 C   Carbon         12.0110 Y     9 C    2     1       9 magnesium carbonate
 6 C   Carbon         12.0110 Y    10 C    2     1      10 sodium bicarbonate
 6 C   Carbon         12.0110 Y    11 C    1     2      11 ethanol
 8 O   Oxygen         15.9990 Y     1 O    2     1       1 water
 8 O   Oxygen         15.9990 Y     2 O    2     2       2 carbon dioxide
 8 O   Oxygen         15.9990 Y     7 O    2     1       7 carbon monoxide
 8 O   Oxygen         15.9990 Y     9 O    3     3       9 magnesium carbonate
 8 O   Oxygen         15.9990 Y    10 O    3     3      10 sodium bicarbonate
 8 O   Oxygen         15.9990 Y    11 O    3     1      11 ethanol
弱骨蛰伏 2024-08-01 02:07:37

如果我理解你的问题,那么你对“TOP”有疑问。 尝试使用 TOP-N 查询。

例如:

select  *
  from  (SELECT  *
           FROM  foo
          where  foo_id=[number]
       order by  foo_id desc)
 where  rownum <= 50

这将为您提供前五十个结果(因为我在子查询中按 desc 排序)

If I understand your question you are having a problem with "TOP". Try using a TOP-N query.

For example:

select  *
  from  (SELECT  *
           FROM  foo
          where  foo_id=[number]
       order by  foo_id desc)
 where  rownum <= 50

This will get you the top fifty results (because I order by desc in the sub query)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文