【问题标题】:Simulating Excel's vlookup with CTEs使用 CTE 模拟 Excel 的 vlookup
【发布时间】:2016-04-26 13:28:42
【问题描述】:

可以使用以下方法从 Excel 中模拟 vlookup 函数:

select b.col, (case when a.val is NULL then 'FALSE' else 'TRUE' end)
from b left outer join
     (select distinct a.val
      from a
     ) a
     on b.col = a.val;

然后可以像这样嵌套多个 CTE:

WITH    cte1 AS
        (
        SELECT  1 AS id
        ),
        cte2 AS
        (
        SELECT  2 AS id
        )
SELECT  *
FROM    cte1
UNION ALL
SELECT  *
FROM    cte2
UNION ALL
SELECT  *
FROM    cte1

问题是:如何通过使用ct1.colct2.col 而不是a.col and b.col 来执行第一个示例中的vlookup?我正在尝试在两个查询输出之间执行 vlookup,而不将它们存储到临时表或表中。

我在想这样的事情:

; with cte1 as ( select pd.value as value from pentd pd
inner join aster a on a.aid = pd.aid
where pid = 10
and a.name = 'ls'),
with cte2 as( select pd.value as value from pentd pd
inner join aster a on a.aid = pd.aid
where pid = 15
and a.name = 'ls' )

select (select value from cte2),
(case 
when cte1.value is null then 'FALSE' else 'TRUE' end)
from cte2
left outer join
(select distinct value from cte1) cte1
on cte1.value = cte2.value

但这回我了(当然上面的代码只是一个例子,不能链接真实的数据或输出)

消息 512,级别 16,状态 1,行 1 子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

知道我想要实现的目标是否可行,如果可以,那么如何在避免错误的同时将其用于多个值?

我正在使用 SQL Server 2012,但我也对 SQL Server 2008 解决方案感兴趣。

cte1 - 此处用于连接的列,因为我只选择值

aid     name     value
10       ls      123.123
10       ls      422.433
10       ls      56.32

cte2 - 此处用于连接的列,因为我只选择值

aid     name     value
15      ls       123.123
15      ls       34.21
15      ls       21.256

预期输出

value
123.123

【问题讨论】:

  • 也许一些具有预期输出的示例数据会使这更容易理解并为您提供有用的答案。在不应该存在子查询的地方使用诸如“cte1”和“pentd”之类的名称以及多个子查询,很难理解您要执行的操作。
  • 好吧,不能真正提供我的数据。但我可以描述这个想法:您有一个表,您可以从中选择一列并将该表与另一个表连接,通过 id 和字符串过滤结果。这是您的第一个cte,第二个是相同的,但使用另一个id。然后使用 cte 中的结果来查找两个值之间的重复项。你不必使用我的专栏,我想要一个例子。只需遵循逻辑:两个 cte 都有一个内部连接和一个 where 子句,它按数字和字符串过滤。您可以使用任何您想要的命名约定。这将有很大帮助,我可以适应
  • 您不需要提供您的实际数据,但如果您能提供 example 数据和预期输出,将会有所帮助。 SO 有一个方便的指南来构建Minimal, Complete, and Verifiable examples
  • 请看我的编辑。 ps:我想避免提供一些数据样本,因为有时人们会提供解决问题的答案,但以不同于问题指南的方式提供。我想使用 CTEs 和 vlookup 函数的模拟。如果这是不可能的,其他解决方案也非常受欢迎!谢谢你的时间
  • @CM2K 只有一个反对票;不要为此感到压力。这可能是因为您的原始修订版(在任何编辑之前)没有样本数据或预期结果,因此很难理解您要做什么。

标签: sql sql-server sql-server-2008 sql-server-2012 common-table-expression


【解决方案1】:
select (select value from cte2),

这条线是你的问题。嵌套查询(括号中的位)返回多个值。您不能将表(即多行)选择为单列。试试这个:

select cte2.value,
(case 
when cte1.value is null then 'FALSE' else 'TRUE' end)
from cte2
left outer join
(select distinct value from cte1) cte1
on cte1.value = cte2.value

如果您需要过滤掉重复项,可以将其更改为 select distinct cte2.value,或者将 distinct 选项迁移到您的 CTE。

【讨论】:

  • 明天我可以访问测试环境时尝试一下。 +1 指出我的方式的错误。谢谢
  • 经过测试,有效。现在的问题是:你真的需要样本数据吗?这是一个我看不到的非常明显的错误,但是像你这样有 sql 经验的人可以很快发现这一点。
  • 在没有样本数据的情况下,错误的位置很明显,但是应该改成什么(意思是你想要的结果是什么)却不是,因为我不擅长Excel。高质量的答案通常需要该信息是完整的,否则它只是一个有用的评论。这也是一个好习惯,因为有时清楚地解释一切可以帮助你自己弄清楚。这就是rubber duck debugging
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
相关资源
最近更新 更多