28

複数のテーブルを結合しようとしていますが、テーブルの 1 つに異なる日付の partid の複数のレコードがあります。最新の日付でレコードを取得したい。

以下にいくつかのテーブルの例を示します。

Table: MyParts
Partid   Partnumber   Description
1        ABC-123      Pipe
2        ABC-124      Handle
3        ABC-125      Light


Table: MyPrices
Partid   Price        PriceDate
1        $1           1/1/2005
1        $2           1/1/2007
1        $3           1/1/2009
2        $2           1/1/2005
2        $4           1/1/2006
2        $5           1/1/2008
3        $10          1/1/2008
3        $12          1/1/2009

特定の部品の最新の価格を知りたい場合は、次のようにします。

SELECT * FROM MyPrice WHERE PriceDate = (SELECT MAX(PriceDate) 
FROM MyPrice WHERE Partid = 1)

ただし、最初に結合を行い、1 つだけでなくすべての部品の正しい価格を取得したいと考えています。これは私が試したことです:

SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE 
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice)

テーブル全体の最高価格日を使用するため、結果は間違っています。

SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE 
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE MyPrice.Partid =   
MyParts.Partid)

それはエラーになります。

望む結果を得るにはどうすればよいか。

4

10 に答える 10

36

サブクエリなしでそれを行う別の方法を次に示します。多くの場合、この方法は他の方法よりも優れているため、両方の方法をテストして、どちらが最高のパフォーマンスを発揮するかを確認する価値があります。

SELECT
     PRT.PartID,
     PRT.PartNumber,
     PRT.Description,
     PRC1.Price,
     PRC1.PriceDate
FROM
     MyParts PRT
LEFT OUTER JOIN MyPrices PRC1 ON
     PRC1.PartID = PRT.PartID
LEFT OUTER JOIN MyPrices PRC2 ON
     PRC2.PartID = PRC1.PartID AND
     PRC2.PriceDate > PRC1.PriceDate
WHERE
     PRC2.PartID IS NULL

同じ正確な PriceDate を持つ 2 つの価格がある場合、これにより複数の結果が得られます (他のほとんどのソリューションでも同じことが行われます)。また、最終価格日が将来であることを説明するものは何もありません。最終的にどの方法を使用するかに関係なく、そのチェックを検討することをお勧めします。

于 2009-05-18T19:00:18.183 に答える
34

これを試して:

Select *,
    Price = (Select top 1 Price 
             From MyPrices 
             where PartID = mp.PartID 
             order by PriceDate desc
            )
from MyParts mp
于 2009-05-18T18:32:43.790 に答える
11
SELECT
    MyParts.*,MyPriceDate.Price,MyPriceDate.PriceDate
    FROM MyParts
        INNER JOIN (SELECT Partid, MAX(PriceDate) AS MaxPriceDate FROM MyPrice GROUP BY Partid) dt ON MyParts.Partid = dt.Partid
        INNER JOIN MyPrice ON dt.Partid = MyPrice.Partid AND MyPrice.PriceDate=dt.MaxPriceDate
于 2009-05-18T18:31:40.253 に答える
5

このようなもの

SELECT * 
FROM MyParts 
LEFT JOIN 
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
 ON MyParts.Partid = MyPrice.Partid 

partid がわかっている場合、または制限できる場合は、それを結合内に配置します。

   SELECT myprice.partid, myprice.partdate, myprice2.Price, * 
    FROM MyParts 
    LEFT JOIN 
    (
    SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
    ) myprice
     ON MyParts.Partid = MyPrice.Partid 
    Inner Join MyPrice myprice2
    on myprice2.pricedate = myprice.pricedate
    and myprice2.partid = myprice.partid
于 2009-05-18T18:33:24.523 に答える
3
SELECT
    *
FROM
    (SELECT MAX(PriceDate) AS MaxP, Partid FROM MyPrices GROUP BY Partid) MaxP 
    JOIN
    MyPrices MP On MaxP.Partid = MP.Partid AND MaxP.MaxP = MP.PriceDate
    JOIN
    MyParts P ON MP.Partid = P.Partid

最初に partid の最新の pricedate を取得し (標準の集計)、それを結合して価格を取得し (集計に含めることはできません)、続いて部品の詳細を取得します。

于 2009-05-18T18:32:24.307 に答える
3

価格表に参加し、最終日のエントリを選択します。

select pa.partid, pa.Partnumber, max(pr.price)
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.PriceDate = (
    select max(PriceDate) 
    from myprices 
    where partid = pa.partid
)

max() は、1 日に複数の価格がある場合に使用します。最高のものを表示したいと思います。価格表に id 列がある場合、 max() を避けて次のように単純化できます。

select pa.partid, pa.Partnumber, pr.price
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.priceid = (
    select max(priceid)
    from myprices 
    where partid = pa.partid
)

PS代わりにwcmのソリューションを使用してください!

于 2009-05-18T18:39:45.617 に答える
2

他のすべての回答は機能する必要がありますが、同じ構文を使用します (およびエラーの理由を理解する)

SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE 
MyPart.PriceDate = (SELECT MAX(MyPrice2.PriceDate) FROM MyPrice as MyPrice2 
WHERE MyPrice2.Partid =  MyParts.Partid)
于 2009-05-18T18:45:11.643 に答える
0

MySQL の場合は、次のクエリを見つけてください。

select * from (select PartID, max(Pricedate) max_pricedate from MyPrices group bu partid) as a 
    inner join MyParts b on
    (a.partid = b.partid and a.max_pricedate = b.pricedate)

サブクエリ内では、MyPrices のすべての partyid の最大 pricedate をフェッチし、partid とmax_pricedateを使用して MyParts と内部結合します。

于 2018-06-25T00:36:29.487 に答える