Welcome to Sign in | Help

Re: Join cu doar primul rand din tabela

  •  09-02-2008, 9:09 AM

    Re: Join cu doar primul rand din tabela

    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
View Complete Thread
Powered by Community Server (Commercial Edition), by Telligent Systems