SQL - 可读性极强,但我不理解其背后的概念

SQL - Extremely human readable, but I don't understand the concepts behind it

我似乎以错误的方式思考 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)

这行得通...但为什么我必须使用 select?

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

其次: 我无法逐行调试,因为 sql 语句被视为一个步骤。我可以调试的唯一方法是,如果我 select 最里面的子查询和 运行 那,然后包括下一个外部子查询和 运行 那,等等。

有本地人吗window?

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

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

tldr: 需要概念基础/知道当我键入内容并按 F5 时实际发生了什么

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

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

关于问题 #1,您需要 select,因为这就是 SQL 的工作原理。你给了它一个名字,但没有告诉它如何处理这个名字(select它,更新它,删除它?)只是说列名在语法上不正确。

关于 #2,是的,SQL 是声明性的,您不是在告诉它 做什么 ,而是在告诉它 return。它将在那个特定时刻及时以最有效的顺序检索数据,通常你的子查询将是最后到运行,而不是第一个。