2014-04-29 128 views
0

我試圖找到一種有效的方式,選擇從現有的表中的第一個相關值,如Excel的VLOOKUP(, , , TRUE)功能會。這是我的,但如果@tableWithData@requiredDates相比非常大,則此代碼效率可能非常低。我覺得我錯過了一些東西。有沒有寫這更好的辦法:SQL相當於Excel的近似VLOOKUP(第一相關值)沒有嵌套查詢

DECLARE @requiredDates TABLE 
(requiredDate datetime) 
INSERT INTO @requiredDates VALUES ('2014-01-01'); 
INSERT INTO @requiredDates VALUES ('2014-01-15'); 
INSERT INTO @requiredDates VALUES ('2014-02-01'); 
INSERT INTO @requiredDates VALUES ('2014-02-15'); 

DECLARE @tableWithData TABLE 
(respectiveDate datetime, 
associatedValue int 
) 
INSERT INTO @tableWithData VALUES ('2014-01-01', 1); 
INSERT INTO @tableWithData VALUES ('2014-02-01', 2); 

SELECT 
    lookupTable.requiredDate, 
    dataTable.associatedValue 
    FROM @tableWithData as dataTable RIGHT JOIN 
    (
    /*Create table which maps the requiredDates -> maxDate highest available date */ 
    SELECT 
     dates.requiredDate, 
     MAX(data.respectiveDate) as maxDate/*, 
     data.associatedValue*/ 
     FROM @requiredDates as dates JOIN @tableWithData as data 
     ON dates.requiredDate >= data.respectiveDate 
     GROUP BY dates.requiredDate 
    ) as lookupTable 
    on lookupTable.maxDate = dataTable.respectiveDate 

注:我使用的MS Server 2005中,但還希望更通用的SQL實現,如果有一個。

回答

0

在Excel中,值爲「TRUE」的vlookup()找到近似匹配。我發現您的查詢有點難以遵循,但下面將獲得小於或等於respectiveDate領域最大的價值:

SELECT dt.associatedValue, 
     (SELECT TOP 1 rd.requiredDate 
     FROM dates.requiredDate rd 
     WHERE rd.requiredDate <= dt.respectiveDate 
     ORDER BY rd.requiredDate DESC 
     ) as RequiredDate 
FROM @tableWithData dt; 

這種結構的查詢將在所有數據庫中工作,需要提醒的是TOP 1可能需要用別的東西替換(limit子句,fetch first 1 rows only子句或其他)。當然,臨時表不會。

在SQL Server中,你也可以使用APPLY表達這一點。

0

我一直在尋找一個解決這個後來意識到數據的,我有型有一個非常簡單的答案,雖然它不完全匹配你的問題,你可能會覺得它有用。想象一下,你試圖運行的查詢是在給定日期誰是統治君主,你有一個君主統治的表。在Excel中,你會做一個VLOOKUP搜索上的統治的開始或結束日期的排序表,但在SQL這是很容易有單獨列在位啓動和統治,結束了查詢,則是

一樣簡單

SELECT * FROM「君主」 WHERE reign_start>日期和reign_end正如我所說的,這是這樣一個簡單的查詢,在某些情況下,如果數據可以被重新配置,以允許它可能是有看頭<日期