我的任务之一是将访问SQL转换为Oracle SQL。 我在MS访问中运行查询,这是关系表,查询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 (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
显然没有用。 所以,我有点切入/粘贴/编辑我的oracle 11g。这就是我得到的:
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:“BRANCH”。“BRANCH_NUM”:标识符无效
联接订单会影响吗? 正如你所看到的,我确实从一个表到另一个表。
语法顺序有问题吗? EX:
INVENTORY.BRANCH_NUM = BRANCH.BRANCH_NUM上的内连接BRANCH 或 BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
的内连接BRANCH这有关系吗?
Oracle SQL中的连接是否按正确顺序正确格式化?
如果是这样,为什么不运行?
旁注,这是一个在线课程,虽然讲师非常专注,但我在这里学到了很多东西,从阅读其他帖子,并问自己的问题。谢谢大家!
答案 0 :(得分:2)
加入顺序很重要,例如check this answer。您无法访问条件之前未引入的表别名,例如您无法在第5行访问BRANCH
,因为它仅在下一个联接中引入。
来自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语法,请不要阅读此答案的其余部分: - )
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变体只是在没有真正帮助的情况下引入语法限制。
答案 1 :(得分:1)
您的原始查询加入了INVENTORY,如下所示:
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;