Domanda

Qual è il modo migliore per trascrivere il seguente codice Transact-SQL in Informix Dynamic Server (IDS) 9.40:

Obiettivo: ho bisogno dei primi 50 ordini con le rispettive righe di ordine

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

Il mio problema è con la sottoselezione perché Informix non consente la PRIMA opzione nella sottoselezione.

Qualche idea semplice ?.

È stato utile?

Soluzione

La risposta ufficiale sarebbe "Si prega di aggiornare da IDS 9.40 poiché non è più supportato da IBM". Cioè, IDS 9.40 non è una versione corrente e (idealmente) non dovrebbe essere utilizzato.

Soluzione per IDS 11.50

Utilizzando IDS 11.50, posso scrivere:

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
    ;

Questo è più o meno equivalente alla tua query. Di conseguenza, se si utilizza una versione corrente di IDS, è possibile scrivere la query utilizzando quasi la stessa notazione di Transact-SQL (utilizzando FIRST al posto di TOP).

Soluzione per IDS 9.40

Cosa puoi fare in IDS 9.40? Mi scusi un momento ... Devo avviare il mio server IDS 9.40.xC7 (questo fix pack è stato rilasciato nel 2005; la versione originale era probabilmente alla fine del 2003) ...

Primo problema: IDS 9.40 non consente le query secondarie nella clausola FROM.

Secondo problema - IDS 9.40 non consente la "PRIMA notazione" in nessuno di questi contesti:

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

Terzo problema - IDS 9.40 non ha un semplice ROWNUM.

Quindi, per ovviare a questi, possiamo scrivere (usando una tabella temporanea - lo rimuoveremo in seguito):

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;

Questo produce la stessa risposta della singola query in IDS 11.50. Possiamo evitare la tabella temporanea? Sì, ma è più dettagliato:

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;

Applicando questo agli ordini originali più l'esempio delle righe d'ordine viene lasciato come esercizio per il lettore.


Sottoinsieme pertinente di schema per "Tabella degli elementi":

-- 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 (sul mio database di esempio):

 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

Altri suggerimenti

Se capisco la tua domanda, stai riscontrando un problema con " TOP " ;. Prova a utilizzare una query TOP-N.

Ad esempio:

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

In questo modo otterrai i primi cinquanta risultati (perché ordino per descrizione nella sottoquery)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top