SQL - 人类可读性极强,但我不明白它背后的概念

Posted

技术标签:

【中文标题】SQL - 人类可读性极强,但我不明白它背后的概念【英文标题】:SQL - Extremely human readable, but I don't understand the concepts behind it 【发布时间】:2017-07-20 13:02:59 【问题描述】:

我似乎以错误的方式思考 sql。我总是写一些不起作用的东西。

例如,我需要一个变量。所以我认为:

DECLARE @CNT AS INT
SET @CNT = COUNT(DISTINCT database.schema.table.column)

为什么这不起作用...?我在这里使用的是完全限定的引用,所以我想要的值应该是明确的。

DECLARE @CNT AS INT
SET @CNT = (SELECT COUNT(DISTINCT database.schema.table.column) FROM column)

这可行...但为什么我必须使用选择?

是否所有内容都必须以 DDL 或 DML 语句之一开头?

其次: 我无法逐行调试,因为一条 sql 语句都被视为一步。我可以调试的唯一方法是,如果我选择最里面的子查询并运行它,然后包含下一个外部子查询并运行它,依此类推。

有本地窗口吗?

我听说过基于集合的思维而不是迭代思维,我想即使对于函数式语言我仍然是迭代的……迭代只是从最里面的括号到最外面的括号,并应用于整个集合。但即使在这里我也遇到了麻烦,因为我不知道集合中的哪个值导致了错误。

对不起,如果这看起来有点散漫……我想这只是反映了我的感受。我不知道如何从许多小组件构建一个大存储过程......就像在 vba 中一样,我可以调用另一个子例程并确保我需要的变量是全局的。

tldr:需要概念基础/了解当我输入内容并按 F5 时实际发生的情况

【问题讨论】:

您需要选择,因为这就是 SQL 的工作方式。您已经给它一个名称,但没有告诉它如何处理该名称(选择它、更新它、删除它?)只是说列名在语法上不正确。在 #2 上,SQL 是声明性的,您不是告诉它要做什么,而是告诉它要返回 什么。它将以最有效的顺序检索数据,这可能意味着或可能不意味着首先运行您的内部 SQL。 SQL 需要多年的经验(或谷歌搜索)来学习所有函数的所有语法。即使它是“人类可读的”,但这并不意味着您可以编写任何您想要的东西。仍然有强制执行的语言规则。 如果您要获取字段数据,您确实需要选择。但是,如果您只是从变量或硬编码值中获取它,那么您可以在不使用 select 的情况下设置它。 F.e. set @Var1 = LEFT(@Var2,8);。但是 COUNT 是一个聚合函数,你总是需要一个选择。 【参考方案1】:

在问题 #1 中,您需要 select,因为 SQL 就是这样工作的。您已经给它一个名称,但没有告诉它如何处理该名称(选择它、更新它、删除它?)只是说列名在语法上不正确。

在#2 上,是的,SQL 是声明性的,你不是告诉它要做什么,而是告诉它要返回什么。它将按照在那个特定时刻最有效的顺序检索数据,通常您的子查询将是最后运行的,而不是第一个运行的。

【讨论】:

我喜欢这样:“你不是告诉它它做什么,而是告诉它要返回什么。”【参考方案2】:

是的,您必须使用SELECT 才能首先获取该数据,然后将其分配给变量。你也可以这样做

DECLARE @CNT AS INT
SELECT @CNT = COUNT(DISTINCT `column`) FROM database.schema.table

【讨论】:

以上是关于SQL - 人类可读性极强,但我不明白它背后的概念的主要内容,如果未能解决你的问题,请参考以下文章

MekaVerse NFT 智能合约正在使用 ECDSA,但我不明白它是如何工作的

Oracle Pl/SQL 中用户定义运算符背后的动机

如何取消任务 - 尝试使用 CancellationTokenSource,但我想我不明白这个概念

网络流最大流

是否有任何经验法则可以根据人类可读的描述构造 SQL 查询?

使用 Moment.js 将人类可读时间转换为 Unix 纪元时间