web-dev-qa-db-ja.com

T-SQLサブクエリの最大値(日付)と結合

複数のテーブルを結合しようとしていますが、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)

エラーが発生します。

希望する結果を得るために何ができますか。

27
MaxGeek

これを試して:

Select *,
    Price = (Select top 1 Price 
             From MyPrices 
             where PartID = mp.PartID 
             order by PriceDate desc
            )
from MyParts mp
31
wcm

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

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

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

32
Tom H
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
10
KM.

2005年にはROW_NUMBER()を使用します。

SELECT * FROM 
    ( SELECT p.*,
        ROW_NUMBER() OVER(PARTITION BY Partid ORDER BY PriceDate DESC) AS rn
    FROM MyPrice AS p ) AS t
WHERE rn=1
5
A-K

このようなもの

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
4
u07ch
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の最新のプライスデート(標準集計)を取得し、次にそれを結合して価格(集計に含めることはできません)を取得してから、パーツの詳細を取得します。

2
gbn

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

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
)

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

2
Andomar

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

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)
1
Eduardo Molteni

次のコード例を試してください:

select t1.*, t2.partprice, t2.partdate 
from myparts t1
join myprices t2 
on t1.partid = t2.partid
where partdate = 
(select max(partdate) from myprices t3 
where t3.partid = t2.partid group by partid)
0
Rupal

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の最大プライスデートを取得し、partidおよびmax_pricedateを使用してMyPartsと内部結合します。

0
Suren