Când ai o problemă de acest gen, e recomandabil să prezinţi structura tabelelor (sub formă de CREATE TABLE, inclusiv constraint-urile aferente) şi date de test (sub formă de INSERT INTO), de exemplu:
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 IA,
B1 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')
INSERT INTO B VALUES (4, 2, 'ABC')
INSERT INTO B VALUES (2, 2, 'BBB')
INSERT INTO B VALUES (3, 2, 'AAA')
Atunci când spui "primul rând din tabela B" trebuie să precizezi în ce ordine vrei să consideri rândurile respective, deoarece rândurile dintr-o tabelă nu au o ordine predefinită (nu contează ordinea în care au fost adăugate). Presupunând că ordinea dorită este dată de coloana B1, rezultatul aşteptat ar putea fi următorul:
ID_A A1 A2 B1
----------- ---------- ---------- ----------
1 X1 Y1 ABC
2 X2 Y2 AAA
3 X3 Y3 NULL
Rezultatul de mai sus poate fi obţinut cu oricare din următoarele query-uri:
SELECT A.*, (SELECT MIN(B1) FROM B WHERE B.ID_A=A.ID_A) B1 FROM A;
SELECT A.*, (SELECT TOP 1 B1 FROM B WHERE B.ID_A=A.ID_A ORDER BY B1) B1 FROM A;
SELECT A.*, MIN(B1) AS B1
FROM A LEFT JOIN B ON B.ID_A=A.ID_A
GROUP BY A.ID_A, A1, A2;
SELECT A.*, X.B1 FROM A LEFT JOIN (
SELECT ID_A, MIN(B1) B1 FROM B
GROUP BY ID_A
) X ON A.ID_A=X.ID_A;
SELECT A.*, X.B1 FROM A LEFT JOIN (
SELECT B.*, ROW_NUMBER() OVER (PARTITION BY ID_A ORDER BY B1) N
FROM B
) X ON A.ID_A=X.ID_A AND X.N=1;
WITH X AS (
SELECT B.*, ROW_NUMBER() OVER (PARTITION BY ID_A ORDER BY B1) N
FROM B
)
SELECT A.*, X.B1 FROM A LEFT JOIN X ON A.ID_A=X.ID_A AND X.N=1
Răzvan