Mysql SQL-理解';加入';语法、顺序
我的任务之一是将access SQL转换为Oracle SQL。 我在MS access中运行了查询,下面是关系表、查询SQL和查询结果: 访问查询SQLMysql SQL-理解';加入';语法、顺序,mysql,sql,oracle,ms-access-2010,Mysql,Sql,Oracle,Ms Access 2010,我的任务之一是将access SQL转换为Oracle SQL。 我在MS access中运行了查询,下面是关系表、查询SQL和查询结果: 访问查询SQL SELECT PUBLISHER.PUBLISHER_CODE, PUBLISHER.PUBLISHER_NAME, BOOK.TITLE, BOOK.TYPE, INVENTORY.BRANCH_NUM, BRANCH.BRANCH_NAME FROM PUBLISHER INNER JOIN (BRANCH INNER JOIN (B
SELECT PUBLISHER.PUBLISHER_CODE, PUBLISHER.PUBLISHER_NAME, BOOK.TITLE, BOOK.TYPE, INVENTORY.BRANCH_NUM, BRANCH.BRANCH_NAME
FROM PUBLISHER INNER JOIN (BRANCH INNER JOIN (BOOK INNER JOIN INVENTORY ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE) ON BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM) ON PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
WHERE (((BOOK.TYPE)='FIC') AND ((BRANCH.BRANCH_NAME)='Henry on the Hill'))
ORDER BY PUBLISHER.PUBLISHER_NAME;
考虑到MS SQL可能在oracle中工作,我尝试了:
SQL> SELECT PUBLISHER.PUBLISHER_CODE, PUBLISHER.PUBLISHER_NAME, BOOK.TITLE, BOOK.TYPE, INVENTORY.BRANCH_NUM, BRANCH.BRANCH_NAME
2 FROM PUBLISHER INNER JOIN (BRANCH INNER JOIN (BOOK INNER JOIN INVENTORY ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE) ON BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM) ON PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
3 WHERE (((BOOK.TYPE)='FIC') AND ((BRANCH.BRANCH_NAME)='Henry on the Hill'))
4 ORDER BY PUBLISHER.PUBLISHER_NAME;
no rows selected
显然,这不起作用。
所以,我在我的Oracle11g中做了一些剪切/粘贴/编辑的事情。以下是我得到的:
SQL> SELECT PUBLISHER.PUBLISHER_CODE, PUBLISHER.PUBLISHER_NAME, BOOK.TITLE, BOOK.TYPE,
2 INVENTORY.BRANCH_NUM, BRANCH.BRANCH_NAME
3 FROM PUBLISHER
4 inner join BOOK ON PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
5 inner join INVENTORY on INVENTORY.BRANCH_NUM = BRANCH.BRANCH_NUM
6 inner join BRANCH on INVENTORY.BRANCH_NUM = BRANCH.BRANCH_NUM
7 where BOOK.BOOK_TYPE = 'FIC'
8 and BRANCH.BRANCH_NAME = 'Henry on the Hill';
inner join INVENTORY on INVENTORY.BRANCH_NUM = BRANCH.BRANCH_NUM
*
ERROR at line 5:
ORA-00904: "BRANCH"."BRANCH_NUM": invalid identifier
那么为什么我会得到这个:
第5行错误:
ORA-00904:“分支”。“分支编号”:无效标识符
连接的顺序会影响什么吗?
正如你们所看到的,我确实按顺序从一张桌子转到另一张桌子
语法顺序重要吗?例:
INVENTORY.BRANCH\u NUM=BRANCH.BRANCH\u NUM上的内部联接分支
或
BRANCH.BRANCH\u NUM=INVENTORY.BRANCH\u NUM上的内部联接分支
那有关系吗
Oracle SQL中的联接是否按照正确的顺序正确格式化
如果是这样,为什么它不运行
旁注,这是一个在线课程,虽然讲师非常专注,但我从阅读其他帖子和问我自己的问题中学到了很多。谢谢大家 您的原始查询如下所示:
inner join INVENTORY ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
试试这个:
select PUBLISHER.PUBLISHER_CODE, PUBLISHER.PUBLISHER_NAME, BOOK.TITLE, BOOK.TYPE, INVENTORY.BRANCH_NUM, BRANCH.BRANCH_NAME
from PUBLISHER
inner join BOOK on PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
inner join INVENTORY on BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
inner join BRANCH on BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
where BOOK.TYPE = 'FIC'
and BRANCH.BRANCH_NAME = 'Henry on the Hill'
order by PUBLISHER.PUBLISHER_NAME;
例如,连接顺序很重要。您无法访问在条件之前未引入的表别名,例如,您无法访问第5行的分支,因为它仅在下一个联接中引入 来自
MS Access
的代码引入了许多括号来限制联接顺序。只需对其应用格式并查看结果:
SELECT
PUBLISHER.PUBLISHER_CODE,
PUBLISHER.PUBLISHER_NAME,
BOOK.TITLE,
BOOK.TYPE,
INVENTORY.BRANCH_NUM,
BRANCH.BRANCH_NAME
FROM
PUBLISHER
INNER JOIN (
BRANCH INNER JOIN (
BOOK INNER JOIN INVENTORY
ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
)
ON BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
)
ON PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
WHERE
(
(
(BOOK.TYPE)='FIC'
)
AND
(
(BRANCH.BRANCH_NAME)='Henry on the Hill'
)
)
ORDER BY
PUBLISHER.PUBLISHER_NAME
移除不需要的支架后,如下所示:
SELECT
PUBLISHER.PUBLISHER_CODE,
PUBLISHER.PUBLISHER_NAME,
BOOK.TITLE,
BOOK.TYPE,
INVENTORY.BRANCH_NUM,
BRANCH.BRANCH_NAME
FROM
PUBLISHER
INNER JOIN BRANCH
INNER JOIN BOOK
INNER JOIN INVENTORY
ON BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
AND
BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
AND
PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
WHERE
BOOK.TYPE='FIC'
AND
(BRANCH.BRANCH_NAME = 'Henry on the Hill')
ORDER BY
PUBLISHER.PUBLISHER_NAME
看起来更好,但只要将ANSI语法转换为普通查询,就可以避免排序问题:警告:ANSI语法funs,请不要阅读此答案的其余部分:-)
SELECT
PUBLISHER.PUBLISHER_CODE,
PUBLISHER.PUBLISHER_NAME,
BOOK.TITLE,
BOOK.TYPE,
INVENTORY.BRANCH_NUM,
BRANCH.BRANCH_NAME
FROM
PUBLISHER,
BRANCH,
BOOK,
INVENTORY
WHERE
BOOK.TYPE='FIC'
AND
(BRANCH.BRANCH_NAME = 'Henry on the Hill')
AND
PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE
AND
BOOK.BOOK_CODE = INVENTORY.BOOK_CODE
AND
BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
ORDER BY
PUBLISHER.PUBLISHER_NAME
由于条件的变化顺序无关紧要,所有条件都放在一起,因此可以按逻辑顺序重新组织:
SELECT
PUBLISHER.PUBLISHER_CODE,
PUBLISHER.PUBLISHER_NAME,
BOOK.TITLE,
BOOK.TYPE,
INVENTORY.BRANCH_NUM,
BRANCH.BRANCH_NAME
FROM
BRANCH,
INVENTORY,
BOOK,
PUBLISHER
WHERE
(BRANCH.BRANCH_NAME = 'Henry on the Hill') -- start from most restrictive
-- condition (concrete branch)
AND
INVENTORY.BRANCH_NUM = BRANCH.BRANCH_NUM -- get all inventory from this branch
AND
BOOK.BOOK_CODE = INVENTORY.BOOK_CODE -- access book specification
-- corresponding to inventory
AND
BOOK.TYPE = 'FIC' -- of specific type
AND
PUBLISHER.PUBLISHER_CODE = BOOK.PUBLISHER_CODE -- and finally find
-- all publishers of that books
ORDER BY
PUBLISHER.PUBLISHER_NAME
因此,在最后一种变体中,可以以人类可读的格式再现查询逻辑。请注意,查询文本中表的顺序(至少在Oracle中,如果您不使用一些特殊提示的话)不会影响真正的查询执行计划,因为优化器会根据需要自行更改它。因此,在大多数情况下,ANSI variant只是引入语法限制,没有真正的帮助。我仍然得到“未选择行”,这对我来说没有意义。如果您提供一些示例数据和模式,我可以进一步帮助您。您的语句“因此ANSI variant在大多数情况下只是引入语法限制,而没有真正的帮助”听起来像是您已经证明的东西,但据我所知,您确实没有。IMO ANSI查询语法在可读性和清晰性方面要好得多,更具自文档性(如预期的联接类型),并且更能防止联接中的错误(如缺少联接),这是您的方法永远无法捕捉到的。除此之外,我发现您的格式更难阅读,并且有多余的注释,例如“对应于清单”,这些注释在ANSI语法中非常清楚。@RedFilter似乎在答案的中间遗漏了一条警告:)不同的人有不同的笔划。因此,国际海事组织对这两种观点来说都是最好的资格。