Dar hai să complicăm puţin problema şi să presupunem că ai mai multe coloane în tabela B:
CREATE TABLE A (
ID_A int PRIMARY KEY,
A1 varchar(10),
A2 varchar(10)
)
CREATE TABLE B (
ID_B int PRIMARY KEY,
ID_A int NOT NULL REFERENCES A,
B1 varchar(10),
B2 varchar(10)
)
INSERT INTO A VALUES (1, 'X1', 'Y1')
INSERT INTO A VALUES (2, 'X2', 'Y2')
INSERT INTO A VALUES (3, 'X3', 'Y3')
INSERT INTO B VALUES (1, 1, 'ABC', '321')
INSERT INTO B VALUES (4, 2, 'ABC', '321')
INSERT INTO B VALUES (2, 2, 'BBB', '222')
INSERT INTO B VALUES (3, 2, 'AAA', '333')
În acest caz, să presupunem că rezultatul dorit ar fi:
ID_A A1 A2 B1 B2
----------- ---------- ---------- ---------- ----------
1 X1 Y1 ABC 321
2 X2 Y2 AAA 333
3 X3 Y3 NULL NULL
4 X4 Y4 CCC 123
(adică pentru fiecare rând din A, dorim primul rând din B, în ordinea dată de B1 şi B2)
Dacă modificăm primul query de mai sus, astfel:
SELECT A.*,
(SELECT MIN(B1) FROM B WHERE B.ID_A=A.ID_A) B1,
(SELECT MIN(B2) FROM B WHERE B.ID_A=A.ID_A) B2
FROM A
atunci obţinem alt rezultat:
ID_A A1 A2 B1 B2
----------- ---------- ---------- ---------- ----------
1 X1 Y1 ABC 321
2 X2 Y2 AAA 222
3 X3 Y3 NULL NULL
4 X4 Y4 CCC 123
pentru că la rândul cu ID_A=2 s-a luat cel mai mic B2, în loc să se ia B2-ul corespunzător rândului cu cel mai mic B1.
Putem obţine rezultatul dorit cu unul din următoarele query-uri:
SELECT X.*,
(SELECT MIN(B2) FROM B WHERE B.ID_A=X.ID_A AND B.B1=X.B1) B2
FROM (
SELECT A.*,
(SELECT MIN(B1) FROM B WHERE B.ID_A=A.ID_A) B1
FROM A
) X
SELECT A.*, B.B1, B.B2 FROM A LEFT JOIN B ON A.ID_A=B.ID_A
AND B.ID_B=(
SELECT TOP 1 ID_B FROM B WHERE A.ID_A=B.ID_A
ORDER BY B1, B2
)
SELECT X.ID_A, X.A1, X.A2, B.B1, B.B2 FROM (
SELECT A.*, (
SELECT TOP 1 ID_B FROM B WHERE A.ID_A=B.ID_A
ORDER BY B1, B2
) ID_B
FROM A
) X LEFT JOIN B ON X.ID_B=B.ID_B
SELECT A.*, X.B1, X.B2 FROM A LEFT JOIN (
SELECT B.*, ROW_NUMBER() OVER (PARTITION BY ID_A ORDER BY B1,B2) N
FROM B
) X ON A.ID_A=X.ID_A AND X.N=1;
Răzvan