2013-03-27 169 views
0

SQL fiddle is here這種自左聯接將返回更多的記錄比我預期

希望我的目標很明確:我有一個存儲「從」貨幣一「到」貨幣表, 「買入」和「賣出」匯率以及匯率應適用的日期。

我想獲取所有貨幣的最新匯率列表,直到給定的截止日期。

這意味着:

  1. 結果應包括「從」 每一行對應一個組合*和「到」貨幣和
  2. 如果有不止一個行的表 使用「從」和「到」貨幣的特定組合,取出的行 應該是具有最近日期的行。

我正在使用的查詢不這樣做。事實上,目前它似乎要返回一切。

SELECT ce.* 
FROM currency_exchange ce 
LEFT JOIN currency_exchange newer 
    ON (
     newer.currency_from = ce.currency_from 
     AND newer.currency_to = ce.currency_to 
     AND newer.exchange_date > ce.exchange_date 
     AND newer.exchange_date <= '2012-03-27 00:00:00' 
    ) 
WHERE newer.id IS NULL 
ORDER BY ce.currency_from, ce.currency_to, ce.exchange_date DESC 

*只是爲了澄清:我將「從」和「到」貨幣算作互斥。如果數據庫中有一行指定從貨幣ID 123到貨幣ID 321的匯率,另一行指定貨幣ID 321到貨幣ID 123的匯率,則應返回這兩行。是的,從123到321的購買率在邏輯上相當於從321到123的銷售率,反之亦然。

+0

我發現我的模糊和誤導性的標籤已經爲我更新,現在好多了總結提問內容:我也瞭解到我所查詢的查詢類型通常被稱爲「每個組最大的n」。網上有很好的資源可以簡要描述這些常見的SQL查詢模式嗎?能夠用正確的術語來描述問題是獲得有用幫助的重要一步。 – Wintermute 2013-03-27 09:51:46

回答

4

關於如何解決這個特定問題有很多方法。我使用的是通過使用子查詢獲取當前交換日期 * currency_from,currency_to *的每個組合。子查詢的結果只有3列,這就是爲什麼我們需要將它加入到原始表格中以獲取剩餘列的原因,前提是它與以下項匹配:currency_from,currency_toexchange_date

SELECT a.* 
FROM currency_exchange a 
     INNER JOIN 
     (
      SELECT currency_from, currency_to, MAX(exchange_date) max_date 
      FROM currency_exchange 
      GROUP BY currency_from, currency_to 
     ) b ON a.currency_from = b.currency_from AND 
       a.currency_to = b.currency_to AND 
       a.exchange_date = b.max_date 

輸出

╔════╦═══════════════╦═════════════╦═════════╦══════════╦═════════════════════╗ 
║ ID ║ CURRENCY_FROM ║ CURRENCY_TO ║ RATE_IN ║ RATE_OUT ║ EXCHANGE_DATE ║ 
╠════╬═══════════════╬═════════════╬═════════╬══════════╬═════════════════════╣ 
║ 20 ║    1 ║   2 ║ 1.43 ║ 1.65  ║ 2013-03-05 15:55:29 ║ 
║ 19 ║    1 ║   3 ║ 1.1  ║ 1.26  ║ 2013-03-05 15:49:45 ║ 
║ 16 ║    2 ║   3 ║ 2  ║ 3  ║ 2012-11-16 15:44:33 ║ 
╚════╩═══════════════╩═════════════╩═════════╩══════════╩═════════════════════╝ 
+0

謝謝 - 看起來像我以後。只是爲了澄清:截止日期約束應該在這個查詢中出現在哪裏?作爲子查詢中的WHERE子句,還是作爲JOIN的附加部分?或者沒有關係? – Wintermute 2013-03-27 09:23:46

+0

在子查詢上添加一個WHERE,因爲子查詢get是最後一行。有一個外部查詢的結果只是爲了得到其餘列。 – 2013-03-27 09:25:03

+0

@RavindraGullapalli你是什麼意思的表結構? 'DESC tableName' – 2013-03-27 09:37:38