2010-11-10 46 views
1

比方說,我有一個Person表和一個採購表與一對多的關係。我想運行一個查詢來返回這個人,只是他們最近的購買。這似乎很容易,但我似乎無法得到它。在SQL中,如何編寫查詢以從1到多關係返回1個記錄?

+0

我認爲我們需要對您的表的詳細信息。人是每個表中的關鍵嗎?你如何在採購表中存儲採購? – prolink007 2010-11-10 21:00:24

+0

什麼決定了哪些購買是最新的 - 日期/時間列可能?併爲什麼數據庫? – 2010-11-10 21:01:06

回答

3

假設你有東西像而purchaseDate列,並希望有一個特定的人(SQL服務器):

SELECT TOP 1 P.Name, P.PersonID, C.PurchaseDescription FROM Persons AS P 
INNER JOIN Purchases AS C ON C.PersonID = P.PersonID 
WHERE P.PersonID = @PersonID 
ORDER BY C.PurchaseDate DESC 
+0

+1適用於T-SQL;除了MSSQL以外,其他的DMBS也會有不同的'TOP'等價物,它們也會做同樣的事情。 – 2010-11-10 21:01:57

0

不知道你的結構在所有的,或者您的DBMS,你會命令的結果通過購買之日起下降/時間,並且只返回第一個join ed記錄。

1

許多數據庫以不同的方式預製「限制或頂部」命令。這裏是一個參考http://troels.arvin.dk/db/rdbms/#select-limit及以下幾樣

如果使用SQL Server

SELECT TOP 1 
    * 
FROM Person p 
INNER JOIN Purchases pc on pc.PersonID = P.PersonID 
Order BY pc.PurchaseDate DESC 

在MySQL應工作

SELECT 
    * 
FROM Person p 
INNER JOIN Purchases pc on pc.PersonID = P.PersonID 
Order BY pc.PurchaseDate DESC 
LIMIT 1 
3
select p.*, pp.* 
from Person p 
left outer join (
    select PersonID, max(PurchaseDate) as MaxPurchaseDate 
    from Purchase 
    group by PersonID 
) ppm 
left outer join Purchase pp on ppm.PersonID = pp.PersonID 
    and ppm.MaxPurchaseDate = pp.PurchaseDate 
where p.PersonID = 42 

這個查詢也將顯示所有最新購買用戶如果刪除WHERE子句。

+0

是啊!使用「group by」和派生表(或內聯視圖)的第一個答案。 – Rawheiser 2010-11-10 21:18:17

+0

+1便攜式,在SQL Server上表現良好。 – onedaywhen 2010-11-11 08:35:45

0

嘗試TOP 1通過在日期desc命令。例如:

CREATE TABLE #One 
(
    id int 
) 

CREATE TABLE #Many 
(
    id int, 
    [date] date, 
    value int 
) 

INSERT INTO #One (id) 
SELECT 1 UNION ALL 
SELECT 2 UNION ALL 
SELECT 3 

INSERT INTO #Many (id, [date], value) 
SELECT 1, GETDATE(), 1 UNION ALL 
SELECT 1, DATEADD(DD, 1 ,GETDATE()), 3 UNION ALL 
SELECT 1, DATEADD(DD, -1 ,GETDATE()), 0 

SELECT TOP 1 * 
    FROM #One O 
    JOIN #Many M ON O.id = M.id 
    ORDER BY [date] DESC 
0

如果您想選擇爲每個人的最新收購,這將是:

SELECT PE.ID, PE.Name, MAx(PU.pucrhaseDate) FROM Persons AS PE JOIN PURCHASE as PU ON PE.ID = PU.Person_ID 

如果你想擁有所有的人還有那些誰沒有購買時,您需要使用左加入。

1

嚴格了我的頭頂!...如果它是那麼只有一個記錄......

SELECT TOP 1 * 
FROM Person p 
    INNER JOIN Purchases pu 
    ON p.ID = p.PersonId 
ORDER BY pu.OrderDate 
WHERE p.ID = *thePersonYouWant* 

否則......

SELECT TOP 1 * 
FROM Person p 
INNER JOIN 
(
SELECT TOP 1 pu.ID 
    FROM Purchases pu 
     ON pu.PersonID = p.Id 
ORDER BY pu.OrderDate 
) sq 

我的想法!我現在還沒有訪問SQL框來測試它。

0

我想你還需要一個名爲Items的表。 PERSONS表將唯一定義每個人及其所有屬性,而ITEMS表將唯一定義每個項目及其屬性。

假設如下:

Persons   |Purchases     |Items 
PerID PerName |PurID PurDt PerID ItemID |ItemID ItemDesc ICost 
101 Joe Smith |201 101107 101 301 |301 Laptop 500 
       |202 101107 101 302 |302 Desktop 699 
102 Jane Doe |203 101108 102 303 |303 iPod  199 
103 Jason Tut |204 101109 101 304 |304 iPad  499 
       |205 101109 101 305 |305 Printer 99 

一人家長可以聯繫到無,一個或多個購買兒童。 一個項目家長可能沒有,一個或多個購買子項。 一個或多個購買兒童將綁定到一個人父母和一個父母。

select per.PerName as Name 
    , pur.PurDt  as Date 
    , itm.ItemDesc as Item 
    , itm.ICost  as Cost 
    from Persons per 
    , Purchases pur 
    , Items  itm 
where pur.PerID = per.PerID   -- For that Person 
    and pur.ItemID = itm.ItemID   -- and that Item 
    and pur.PurDt =     -- and the purchase date is 
    (Select max(lst.PurDt)   -- the last date 
     from Purchases lst   -- purchases 
     where lst.PerID = per.PerID) -- for that person 

這應返回:

Name   Date Item Cost 
Joe Smith 101109 Ipad  499 
Joe Smith 101109 Printer 99 
Jane Doe  101108 iPod  199