FIRSTオプションを使用したInformixのサブクエリ
-
06-07-2019 - |
質問
次の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ではサブセレクトの最初のオプションが許可されていないため、サブセレクトに問題があります。
簡単なアイデアは?。
解決
公式の答えは、「IBMでサポートされなくなったため、IDS 9.40からアップグレードしてください」です。つまり、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とほぼ同じ表記法を使用して(TOPの代わりにFIRSTを使用して)クエリを記述できます。
IDS 9.40のソリューション
IDS 9.40でできることすみません... IDS 9.40.xC7サーバーを実行する必要があります(このフィックスパックは2005年にリリースされました。元のリリースはおそらく2003年後半にありました)...
最初の問題-IDS 9.40では、FROM句でサブクエリを使用できません。
2番目の問題-IDS 9.40では、次のいずれのコンテキストでも「FIRST n」表記が許可されていません。
SELECT FIRST 10 * FROM elements INTO TEMP e;
INSERT INTO e SELECT FIRST 10 * FROM elements;
3番目の問題-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;
これを元の注文と注文明細の例に適用することは、読者の演習として残されています。
「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)
);
出力(サンプルデータベース上):
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
他のヒント
質問を理解した場合、「TOP」に問題があります。 TOP-Nクエリを使用してみてください。
例:
select *
from (SELECT *
FROM foo
where foo_id=[number]
order by foo_id desc)
where rownum <= 50
これにより、上位50件の結果が得られます(サブクエリでdescで注文するため)