첫 번째 옵션이있는 Informix 하위 Queries
-
06-07-2019 - |
문제
IDS (Informix Dynamic Server) 9.40에 다음 Transact-SQL 코드를 전사하는 가장 좋은 방법은 무엇입니까?
목표 : 각각의 주문 라인이있는 처음 50 개의 주문이 필요합니다.
select *
from (select top 50 * from orders) a inner join lines b
on a.idOrder = b.idOrder
내 문제는 Informix가 subselect에서 첫 번째 옵션을 허용하지 않기 때문에 subselect에 관한 것입니다.
간단한 아이디어?.
해결책
공식 답변은 'IBM이 더 이상 지원되지 않으므로 IDS 9.40에서 업그레이드하십시오'입니다. 즉, IDS 9.40은 현재 버전이 아니며 (이상적으로는) 사용되지 않아야합니다.
ID에 대한 솔루션 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
;
이것은 쿼리와 다소 동일합니다. 결과적으로 현재 버전의 ID를 사용하는 경우 Transact-SQL과 거의 동일한 표기법을 사용하여 쿼리를 작성할 수 있습니다 (먼저 상단 대신 사용).
IDS 9.40 용 솔루션
ID 9.40에서 무엇을 할 수 있습니까? 실례합니다 ... 나는 IDS 9.40.xc7 서버를 실행해야합니다 (이 수정 팩은 2005 년에 출시되었으며 원래 릴리스는 아마도 2003 년 후반에 있었을 것입니다) ...
첫 번째 문제 -IDS 9.40은 FROM 절에서 하위 쿼리를 허용하지 않습니다.
두 번째 문제 -ID 9.40은 이러한 맥락 중 하나에서 '첫 번째 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;
이것은 ID 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
다른 팁
내가 당신의 질문을 이해한다면 당신은 "TOP"에 문제가 있습니다. Top-N 쿼리를 사용해보십시오.
예를 들어:
select *
from (SELECT *
FROM foo
where foo_id=[number]
order by foo_id desc)
where rownum <= 50
이렇게하면 상위 50 개의 결과가 나옵니다 (하위 쿼리에서 DESC로 주문하기 때문에).