web-dev-qa-db-fra.com

Inscrivez-vous uniquement au "dernier" enregistrement avec t-sql

J'ai deux tables. La table "B" a une relation un à plusieurs avec la table "A", ce qui signifie qu'il y aura de nombreux enregistrements dans la table "B" pour un enregistrement dans la table "A".

Les enregistrements de la table "B" sont principalement différenciés par une date. Je dois produire un jeu de résultats comprenant l'enregistrement de la table "A" jointe à seulement la dernière fiche de la table "B". À titre d’illustration, voici un exemple de schéma:

Table A
-------
ID

Table B
-------
ID
TableAID
RowDate

Je ne parviens pas à formuler la requête pour me donner les résultats. Je recherche une aide qui serait grandement appréciée.

19
Joel Martinez
select a.*, bm.MaxRowDate
from (
    select TableAID, max(RowDate) as MaxRowDate
    from TableB
    group by TableAID
) bm
inner join TableA a on bm.TableAID = a.ID

Si vous avez besoin de plus de colonnes de TableB, procédez comme suit:

select a.*, b.* --use explicit columns rather than * here
from (
    select TableAID, max(RowDate) as MaxRowDate
    from TableB
    group by TableAID
) bm
inner join TableB b on bm.TableAID = b.TableAID
    and bm.MaxRowDate = b.RowDate
inner join TableA a on bm.TableAID = a.ID
24
RedFilter
SELECT *
FROM tableA A
OUTER APPLY (SELECT TOP 1 * 
             FROM tableB B
             WHERE A.ID = B.TableAID
             ORDER BY B.RowDate DESC) as B
29
Philip Fourie
With ABDateMap AS (
    SELECT Max(RowDate) AS LastDate, TableAID FROM TableB GROUP BY TableAID
),
LatestBRow As (
    SELECT MAX(ID) AS ID, TableAID FROM ABDateMap INNER JOIN TableB ON b.TableAID=a.ID AND b.RowDate = LastDate GROUP BY TableAID
)
SELECT columns
FROM TableA a
INNER JOIN LatestBRow m ON m.TableAID=a.ID
INNER JOIN TableB b on b.ID = m.ID
3
Joel Coehoorn

la jointure table B est optionnelle: cela dépend s'il y a d'autres colonnes que vous voulez

SELECT
    *
FROM
    tableA A
    JOIN
    tableB B ON A.ID = B.TableAID
    JOIN
    (
    SELECT Max(RowDate) AS MaxRowDate, TableAID
    FROM tableB
    GROUP BY TableAID
    ) foo ON B.TableAID = foo.TableAID AND B.RowDate= foo.MaxRowDate
2
gbn

Juste pour des raisons de clarté et au profit de ceux qui tomberont sur cette ancienne question. La réponse acceptée renverrait les lignes en double s'il y a une copie RowDate dans Table B. Une méthode plus sûre et plus efficace consisterait à utiliser ROW_NUMBER():

Select a.*, b.* -- Use explicit column list rather than * here
From [Table A] a
Inner Join ( -- Use Left Join if the records missing from Table B are still required
    Select *,
        ROW_NUMBER() OVER (PARTITION BY TableAID ORDER BY RowDate DESC) As _RowNum
    From [Table B]
) b
On b.TableAID = a.ID
Where b._RowNum = 1
1
Y.B.

Essayez d'utiliser ceci:

    BEGIN

DECLARE @TB1 AS TABLE (ID INT, NAME VARCHAR(30) )
DECLARE @TB2 AS TABLE (ID INT, ID_TB1 INT, PRICE DECIMAL(18,2))

INSERT INTO @TB1 (ID, NAME) VALUES (1, 'PRODUCT X')
INSERT INTO @TB1 (ID, NAME) VALUES (2, 'PRODUCT Y')

INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (1, 1, 3.99)
INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (2, 1, 4.99)
INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (3, 1, 5.99)

INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (1, 2, 0.99)
INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (2, 2, 1.99)
INSERT INTO @TB2 (ID, ID_TB1, PRICE) VALUES (3, 2, 2.99)


SELECT A.ID, A.NAME, B.PRICE
  FROM @TB1 A
  INNER JOIN @TB2 B ON A.ID = B.ID_TB1 AND B.ID = (SELECT MAX(ID) FROM @TB2 WHERE ID_TB1 = A.ID)


END
0
Paulo Marques

Cela ira chercher le dernier enregistrement avec JOIN. Je pense que cela aidera quelqu'un

SELECT cmp.*, lr_entry.lr_no FROM 
(SELECT * FROM lr_entry ORDER BY id DESC LIMIT 1) 
lr_entry JOIN companies as cmp ON cmp.id = lr_entry.company_id
0