SQL:没有FROM子句的子查询

时间:2017-06-28 18:19:21

标签: sql sql-server tsql sql-server-2012

这是表结构

CREATE TABLE Book_Tag (id INT, Book_Id INT, tag varchar(20))

CREATE TABLE Book_Master (Book_Id INT, Book_title VARCHAR(50), price INT)

数据看起来像这样:

INSERT INTO Book_Master
SELECT 1, 'Good Profit', 28 UNION ALL
SELECT 2, 'The Secret', 20 UNION ALL
SELECT 3, 'The One Minute Manager', 9 UNION ALL
SELECT 4, 'The 7 Habits of Highly Effective People', 35 UNION ALL
SELECT null, 'Who Moved My Cheese?', 15 UNION ALL
SELECT null, 'Blink: The Power of Thinking Without Thinking', 40

INSERT INTO Book_Tag
SELECT 1, 1, 'Management' UNION ALL
SELECT 2, 1, 'Profit' UNION ALL
SELECT 3, 2, 'Mind' UNION ALL
SELECT 4, 3, 'Management' UNION ALL
SELECT 5, 3, 'Efficiency' UNION ALL
SELECT 6, 3, 'Success' UNION ALL
SELECT 7, 4, 'Success' UNION ALL
SELECT 8, null, 'Time' UNION ALL
SELECT 9, 6, 'SelfHelp' UNION ALL
SELECT 10, 6, 'Motivation' UNION ALL
SELECT 11, 8, 'Mind'

select * from Book_Master

Book_Id Book_title                                      price
1           Good Profit                                     28
2           The Secret                                      20
3           The One Minute Manager                          9
4           The 7 Habits of Highly Effective People         35
NULL        Who Moved My Cheese?                            15
NULL        Blink: The Power of Thinking Without Thinking   40

select * from Book_Tag

id  Book_Id tag
1   1       Management
2   1       Profit
3   2       Mind
4   3       Management
5   3       Efficiency
6   3       Success
7   4       Success
8   NULL    Time
9   6       SelfHelp
10  6       Motivation
11  8       Mind

我不知道为什么以下是有效的,也是为什么结果如此。

select BT.* from Book_Tag BT
where BT.Book_Id in (select id)

id  Book_Id tag
1   1       Management

或者

select BT.* from Book_Tag BT
where BT.Book_Id not in (select id)

id  Book_Id tag
2   1       Profit
3   2       Mind
4   3       Management
5   3       Efficiency
6   3       Success
7   4       Success
9   6       SelfHelp
10  6       Motivation
11  8       Mind

2 个答案:

答案 0 :(得分:0)

你在这里询问" BT.Book_Id在(选择id)"中的位置是说Book_ID = ID。所以在这种情况下它打印出来。 Book_ID和ID都是1.然后不是,当它们不相等时,这就是该表中的所有其他内容。

答案 1 :(得分:0)

您的第一个查询:

select BT.* 
from Book_Tag BT
where BT.Book_Id in (select id); 

与以下内容相同:

select BT.* 
from Book_Tag BT
where BT.Book_Id = BT.id;

这就是你得到的原因

1 1 Management

请注意,NULL不等于NULL或其他任何内容。

在第二个例子中,你有:

select BT.* 
from Book_Tag BT
where BT.Book_Id not in (select id);

与以下内容相同:

select BT.* 
from Book_Tag BT
where BT.Book_Id <> BT.id;

请注意,没有 8 NULL Time行。

修改

  

但是,在Subquery中我们不应该指定id来自的表。

来自MSDN

  

一般规则是语句中的列名由同一级别的FROM子句中引用的表隐式限定。 如果子查询的FROM子句中引用的表中不存在列,则它将由外部查询的FROM子句中引用的表隐式限定。

  

如果子查询中引用的列在子查询的FROM子句引用的表中不存在,但存在于外部查询的FROM子句引用的表中,则查询执行没有错误。 SQL Server使用外部查询中的表名隐式地限定子查询中的列。