SQL等价的Excel没有嵌套查询的近似VLOOKUP(第一个相关值)

时间:2014-04-29 14:10:52

标签: sql sql-server excel tsql nested

我正在尝试找到一种有效的方法来从现有表中选择第一个相关值,就像Excel的VLOOKUP( , , , TRUE)函数一样。这就是我所拥有的,但如果@tableWithData@requiredDates相比非常大,则此代码的效率非常低。我觉得我错过了什么。有没有更好的方式来写这个:

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实现。

2 个答案:

答案 0 :(得分: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表达此内容。

答案 1 :(得分:0)

我正在寻找一个解决方案然后意识到,对于我所拥有的数据类型,有一个非常简单的答案,虽然它不能完全匹配您的问题,但您可能会发现它很有用。想象一下,你试图运行的查询是谁在给定日期的统治君主,你有一个君主统治的表。在excel中,你可以在一个排序的表格上进行vlookup搜索,这个表格包含了统治的开始日期或结束日期,但是在SQL中,为reign-start和reign-end查询单独的列要容易得多,然后就像

SELECT * FROM'monarchs'WHERE reign_start&gt; date AND reign_end&lt;日期

正如我所说,这是一个如此简单的查询,在某些情况下,可能值得查看数据是否可以重新配置以允许它。