最初,我有一个名为acc_account的表,其中列出了公司或组织使用的所有帐户。假设我在这个表中有518行:
500行是使用的帐户,另外18行描述不同类型的帐户。它用于在会计应用程序中创建报告。我不知道为什么他们将2个不同的部分包含在一个表中,但它是这样创建的。
无论如何,这个存储过程名为acc_qry_chart_of_accounts,基本上它列出了组织/公司使用的所有帐户。
在存储过程本身内部学习时,我发现了一些理解查询的问题,这是我在下面展示的内容。
基本上,因为有18行包含在一起,所以18行中的一些不得显示在结果中,例如:我们没有任何账户类型的'EI'(特殊收入)。我必须从结果中排除它。
下面的查询是他们用来排除这些帐户的示例,我个人不明白为什么父列(aka parent_code)可以与acc_code相同,为什么它必须使用不同的别名?
所以,我决定问这个关于查询本身的问题,这就是为什么我在这里。
我内部使用不同的别名加入一个表。
然后,我使用此查询创建一个查询WHERE
EXISTS
'parent'列等于'acc_code'列:
SELECT * FROM acc_account
INNER JOIN acc_account a2 ON acc_account.acc_code=a2.acc_code
WHERE EXISTS (SELECT * FROM acc_account WHERE acc_account.parent=a2.acc_code);
结果如下:
acc_id acc_code parent name
------- ------------------ --------- ---------------------------
2 | CA | -1 | CURRENT ASSETS
3 | CL | -1 | CURRENT LIABILITIES
4 | CP | -1 | CAPITAL/RETAINED EARNINGS
5 | CS | -1 | COST OF GOODS SALES
7 | EX | -1 | EXPENSES
您可以看到父数据和acc_code数据首先不相等,但它产生了上面的输出。
现在,当我使用相同的查询但将acc_account.parent=a2.acc_code
之前的最后一行更改为acc_account.parent=acc_account.acc_code
时:
SELECT * FROM acc_account
INNER JOIN acc_account a2 ON acc_account.acc_code=a2.acc_code
WHERE EXISTS (SELECT * FROM acc_account WHERE acc_account.parent=acc_account.acc_code);
结果:
acc_id acc_code parent name
------- ------------------ --------- ---------------------------
| | |
没有应有的结果。那么为什么首先如果我尝试使用不同的别名,它会产生不同的结果呢?
以下查询返回0行:
select * from acc_account where parent=acc_code;
我的问题,a1
& a2
是同一张桌子还是我弄错了?
条件a1.parent=a2.acc_code
与a1.parent=a1.acc_code
相同,在这种情况下,两个表相同且包含相同的数据?
答案 0 :(得分:1)
您正在编写的查询基本上是这样的:
SELECT a.*
FROM acc_account a INNER JOIN
acc_account a2
ON a.acc_code = a2.acc_code
WHERE EXISTS (SELECT 1 FROM acc_account a3 WHERE a3.parent = a2.acc_code);
三个对acc_account
的单独引用。子查询中引用的parent
与输出的父项无关。
您修改的查询只是删除了相关原因而没有匹配的行,因此不会返回任何内容。
答案 1 :(得分:0)
您的第一个查询:
SELECT *
FROM acc_account
INNER JOIN acc_account a2
ON acc_account.acc_code = a2.acc_code
WHERE EXISTS (
SELECT *
FROM acc_account
WHERE acc_account.parent = a2.acc_code
);
搜索父acc_account
。由于您在SELF JOIN
子句中使用了相同的列,因此ON
非常重要。没有它,SELF JOIN
的结果将是相同的。然后,WHERE
子句使用以下条件检查父acc_account
:
WHERE acc_account.parent = a2.acc_code
您的第二个问题:
SELECT *
FROM acc_account
INNER JOIN acc_account a2
ON acc_account.acc_code = a2.acc_code
WHERE EXISTS (
SELECT *
FROM acc_account
WHERE
acc_account.parent = acc_account.acc_code
);
除了WHERE
子句之外,与第一个相同。这里:
SELECT *
FROM acc_account
WHERE
acc_account.parent = acc_account.acc_code
由于没有acc_count
是其自身的父级,因此它不返回任何行,导致EXISTS
条件为FALSE
,并且查询不返回任何行。 / p>
请注意,由于acc_account
被多次引用,其中两个没有别名,因此子查询中的条件为:
acc_account.parent = acc_account.acc_code
引用子查询中的表,最近的一个表示比较同一行但不同的列。
你想要的是:
SELECT *
FROM acc_account a1
WHERE EXISTS (
SELECT *
FROM acc_account a2
WHERE
a2.parent = a1.acc_code
);
这就是别名的重要性所在。