Informix Unterabfragen mit FIRST Option
-
06-07-2019 - |
Frage
Was ist der beste Weg, um den folgenden Transact-SQL-Code zu Informix Dynamic Server (IDS) 9,40 transkribieren:
Ziel: Ich brauche die ersten 50 Aufträge mit ihren jeweiligen Auftragszeilen
select *
from (select top 50 * from orders) a inner join lines b
on a.idOrder = b.idOrder
Mein Problem ist, mit dem subselect weil Informix der ersten Option in der subselect nicht gestattet.
Jede einfache Idee?.
Lösung
Die offizielle Antwort wäre ‚Bitte aktualisieren Sie von IDS 9.40, da sie nicht mehr von IBM unterstützt wird‘. Das heißt, IDS 9.40 ist keine aktuelle Version -. Und sollte (idealerweise) nicht verwendet werden
Lösung für IDS 11.50
Mit IDS 11.50, kann ich schreiben:
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
;
Dies ist mehr oder weniger äquivalent zu Ihrer Anfrage. Wenn Sie also eine aktuelle Version von IDS verwenden, können Sie die Abfrage mit fast die gleichen Schreibweise wie in Transact-SQL (mit FIRST anstelle von TOP) schreiben.
Lösung für IDS 9.40
Was können Sie tun, in IDS 9.40? Entschuldigen Sie mich einen Moment ... Ich habe meine IDS 9.40.xC7 Server laufen (dieser Fix Pack wurde im Jahr 2005 veröffentlicht, die ursprüngliche Release war wahrscheinlich Ende 2003) ...
Das erste Problem - IDS 9.40 nicht Unterabfragen in der FROM-Klausel erlauben
.Zweites Problem - IDS 9.40 erlaubt es nicht, 'FIRST n' Notation in einem diesen Kontexten:
SELECT FIRST 10 * FROM elements INTO TEMP e;
INSERT INTO e SELECT FIRST 10 * FROM elements;
Drittes Problem -. IDS 9.40 keine einfache ROWNUM hat
Also, um diese zu arbeiten, können wir schreiben (eine temporäre Tabelle mit - wir entfernen, dass später):
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;
Dies erzeugt die gleiche Antwort wie die einzelne Abfrage in IDS 11.50. Können wir die temporäre Tabelle vermeiden? Ja, aber es ist ausführlicher:
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;
Die Anwendung, die auf die ursprünglichen Aufträge sowie auch Beispielauftragszeilen als eine Übung für den Leser überlassen wird.
Relevante Teilmenge des Schemas für '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)
);
Ausgabe (auf meiner Beispieldatenbank):
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
Andere Tipps
Wenn ich verstehe Ihre Frage, die Sie ein Problem mit „TOP“ haben. Versuchen Sie es mit einer Top-N-Abfrage.
Zum Beispiel:
select *
from (SELECT *
FROM foo
where foo_id=[number]
order by foo_id desc)
where rownum <= 50
Dies wird Ihnen die besten fünfzig Ergebnisse bekommen (weil ich ab in die Sub-Abfrage zu bestellen)