简体   繁体   中英

Getting last record on join from one to many relationship Firebird

I'm currently working on a Firebird database where the product to product cost table is one to many. I need to include the most current cost (highest ID) in product listing script.

I'm not sure how to do this on a one to many relation.

select SPLU.SHOPPRODUCTSPLUID,SPLU.plu, SPLU.description, SPLU.SHOPPRODUCTSID,
       SG.GROUPNAME, SCOST.NORMALCOST, splu.sellprice1, SSL.NAME as fmSuppliername,
       sdl.NAME as fmDeptName,SS.MAINSUPPLIER as fmMainSupplier, SS.UNITSPERCARTON as UPC
from SHOPPRODUCTSPLU SPLU
join SHOPPRODUCTS SP
    on SP.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID 
join SHOPGROUPLOOKUP SG
    on SG.SHOPGROUPLOOKUPID = SP.SHOPGROUPLOOKUPID and SP.STOREID = SG.STOREID 
join SHOPSUPPLIER SS
    on SS.SHOPPRODUCTSID = SP.SHOPPRODUCTSID and SS.STOREID = SP.STOREID
JOIN SHOPSUPPLIERLOOKUP SSL
    ON SSL.SHOPSUPPLIERLOOKUPID = SS.SHOPSUPPLIERLOOKUPID
join SHOPDEPTLOOKUP SDL
    ON SDL.SHOPDEPTLOOKUPID = SG.SHOPDEPTLOOKUPID
join SHOPPRODUCTSCOSTHST SCOST
    on SCOST.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID 
where SP.STOREID = 1 and SPLU.ACTIVEITEM = 'TRUE' and SP.ACTIVEITEM = 'TRUE'

My join on SHOPPRODUCTSCOSTHST will now bring in a record for every cost in the table below when we only need the newest.

成本表

Current output

在此处输入图像描述

One solution would be to add a condition to the join on SHOPPRODUCTSCOSTHST that filters on the matching record that has the highest id:

join SHOPPRODUCTSCOSTHST SCOST
    on SCOST.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID 
    and SCOST.SHOPPRODUCTSCOSTHSID = (
        select max(SCOST1.SHOPPRODUCTSCOSTHSID)
        from SHOPPRODUCTSCOSTHST SCOST1
        where SCOST1.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID
    )

If SHOPPRODUCTSCOSTHSID is a unique key in table SHOPPRODUCTSCOSTHST , this can be simplified a little:

join SHOPPRODUCTSCOSTHST SCOST
    on SCOST.SHOPPRODUCTSCOSTHSID = (
        select max(SCOST1.SHOPPRODUCTSCOSTHSID)
        from SHOPPRODUCTSCOSTHST SCOST1
        where SCOST1.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID
    )

For performance here, you want an index on SCOST(SHOPPRODUCTSID, SHOPPRODUCTSCOSTHSID) .

One possible solution is to use a CTE.

Some factors in which you wouldn't want to use the method i am proposing is if your SHOPPRODUCTSCOSTHST table has a large number of rows. Another factor would be if this query is executed very frequently.

The CTE would be used to get the MAX ID of SHOPPRODUCTSCOSTHST grouped by SHOPPRODUCTSID. Then I would use that CTE in the main query and constrain your INNER JOIN SCOST on CTE.MAX_SHOPPRODUCTSCOSTHSTID = SCOST.SHOPPRODUCTSCOSTHSTID. That would return only one row per SHOPPRODUCTSID.

below is an example.

  WITH MAXCOSTHST
    AS (
        SELECT SHOPPRODUCTSID
            ,MAX(SHOPPRODUCTSCOSTHSTID) MAX_SHOPPRODUCTSCOSTHSTID
        FROM SHOPPRODUCTSCOSTHST
        GROUP BY SHOPPRODUCTSID
        )
    SELECT SPLU.SHOPPRODUCTSPLUID
        ,SPLU.plu
        ,SPLU.description
        ,SPLU.SHOPPRODUCTSID
        ,SG.GROUPNAME
        ,SCOST.NORMALCOST
        ,splu.sellprice1
        ,SSL.NAME AS fmSuppliername
        ,sdl.NAME AS fmDeptName
        ,SS.MAINSUPPLIER AS fmMainSupplier
        ,SS.UNITSPERCARTON AS UPC
    FROM SHOPPRODUCTSPLU SPLU
    JOIN SHOPPRODUCTS SP ON SP.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID
    JOIN SHOPGROUPLOOKUP SG ON SG.SHOPGROUPLOOKUPID = SP.SHOPGROUPLOOKUPID
        AND SP.STOREID = SG.STOREID
    JOIN SHOPSUPPLIER SS ON SS.SHOPPRODUCTSID = SP.SHOPPRODUCTSID
        AND SS.STOREID = SP.STOREID
    JOIN SHOPSUPPLIERLOOKUP SSL ON SSL.SHOPSUPPLIERLOOKUPID = SS.SHOPSUPPLIERLOOKUPID
    JOIN SHOPDEPTLOOKUP SDL ON SDL.SHOPDEPTLOOKUPID = SG.SHOPDEPTLOOKUPID
    JOIN MAXCOSTHST ON MAXCOSTHST.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID
    JOIN SHOPPRODUCTSCOSTHST SCOST ON SCOST.SHOPPRODUCTSID = SPLU.SHOPPRODUCTSID
        AND MAXCOSTHST.MAX_SHOPPRODUCTSCOSTHSTID = SCOST.SHOPPRODUCTSCOSTHSTID
    WHERE SP.STOREID = 1
        AND SPLU.ACTIVEITEM = 'TRUE'
        AND SP.ACTIVEITEM = 'TRUE'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM