为什么 SQL 查询不能用于子查询但可以用于逗号分隔列表?

为什么 SQL 查询不能用于子查询但可以用于逗号分隔列表?

我有疑问:

SELECT p.[id], p.[page_file], p.[page_header], p.[page_icon] 

FROM [dbo].[setup_pages] AS p 

WHERE CONVERT(nvarchar(100),p.[id]) IN ( SELECT l.[access] FROM [dbo].[licenses] AS l )

它没有返回错误,也没有返回任何数据。

SELECT l.[access] FROM [dbo].[licenses] AS l返回 3 行:
1)8,9,15,4,13,11,5,14,12,16
2)20,19
3)20,8,9,15,4,13,11,5,14,12,16

如果我运行这样的查询:

SELECT p.[id], p.[page_file], p.[page_header], p.[page_icon] 

FROM [dbo].[setup_pages] AS p 

WHERE CONVERT(nvarchar(100),p.[id]) IN ( 8,9,15,4,13,11,5,14,12,16 )

它确实有效。...我的问题在哪里?

答案1

access根据您的描述,表中的列似乎licenses是一个包含字符串的字符列 - 其内容是以逗号分隔的数字列表。

因此,如果我们提取该结果SELECT l.[access] FROM [dbo].[licenses] AS l并假装将其直接放入IN,它看起来就不像您的第二个查询 - 相反,它看起来像这样:

SELECT p.[id], p.[page_file], p.[page_header], p.[page_icon] 
FROM [dbo].[setup_pages] AS p 
WHERE CONVERT(nvarchar(100),p.[id]) IN (
  '8,9,15,4,13,11,5,14,12,16',
  '20,19',
  '20,8,9,15,4,13,11,5,14,12,16'
)

现在很清楚为什么第一个查询会失败 - 特定的idfromsetup_pages永远不会匹配 中的任何字符串licenses.access。您可能需要查看数据库模型,并可能access用“m:n”映射表替换该列。

顺便说一句:看起来您正在尝试使用CONVERT()id字段转换为字符串,但这仍然不会使其与包含多个数字的字符串匹配,并且它也是不必要的 - 根据 SQL 标准,数据库服务器需要在简单的情况下自动执行此类转换,这就是为什么您的第二个查询实际上有效的原因,即使它将id字符串形式的值与未格式化为字符串的数字列表进行比较。

相关内容