sql - SQL 中的别名作用域

标签 sql sqlite

我在 SQLite3 数据库上进行复杂查询时遇到问题,我认为这与我对如何引用 select 语句返回的结果表中的列的误解有关,尤其是在涉及别名时.

下面是一个示例表 - 电影 ID 列表,其中一行代表电影中的每个 Actor :

CREATE TABLE movie_actor (imdb_id TEXT, actor TEXT);
INSERT INTO movie_actor VALUES('44r4', 'John Doe');
INSERT INTO movie_actor VALUES('44r4', 'Jane Doe');
INSERT INTO movie_actor VALUES('44r4', 'Jermaine Doe');
INSERT INTO movie_actor VALUES('44r4', 'Jacob Doe');
INSERT INTO movie_actor VALUES('55r5', 'John Doe');
INSERT INTO movie_actor VALUES('55r5', 'Jane Doe');
INSERT INTO movie_actor VALUES('55r5', 'Nathan Deer');
INSERT INTO movie_actor VALUES('66r6', 'Bob Duck');
INSERT INTO movie_actor VALUES('66r6', 'John Doe');
INSERT INTO movie_actor VALUES('66r6', 'Jermaine Doe');
INSERT INTO movie_actor VALUES('66r6', 'Jane Doe');
INSERT INTO movie_actor VALUES('77r7', 'John Doe');

我试图找出每对 Actor 在所有电影中合作的次数。我决定通过自连接来解决这个问题,但遇到了一些问题,我会得到诸如“John Doe,Jane Doe,3”和“Jane Doe,John Doe,3”之类的记录对 - 这实际上是同一件事,我只想计算第一个版本。这是生成的代码:

SELECT DISTINCT 
    CASE WHEN d.actor_1 > d.actor_2 THEN d.actor_1 ELSE d.actor_2 END d.actor_1, 
    CASE WHEN d.actor_2 > d.actor_1 THEN d.actor_2 ELSE d.actor_1 END d.actor_2, 
    d.v 
FROM ( 
    SELECT c.actor_1 AS actor_1, c.actor_2 AS actor_2, COUNT(*) AS v 
    FROM ( 
        SELECT a.actor AS actor_1, b.actor AS actor_2 
        FROM movie_actor a JOIN movie_actor b ON a.imdb_id=b.imdb_id 
        ) AS c 
    WHERE c.actor_1 <> c.actor_2 
    GROUP BY c.actor_1, c.actor_2 
    HAVING COUNT(*) > 2 
    ORDER BY COUNT(*) DESC 
    LIMIT 20 
    ) 
    AS d

这无法运行,但我不明白为什么。我的假设是我没有正确使用别名,但我真的不知道。有什么想法吗?

( SQL Fiddle link here )

最佳答案

如果我们添加条件a.actor < b.actor,我们会得到一个更简单的查询。这排除了具有相同 Actor 的配对,同时也消除了交换 Actor 的需要。

SELECT
    a.actor AS actor_1, b.actor AS actor_2, COUNT(*) AS v
FROM
    movie_actor a
    INNER JOIN movie_actor b
        ON a.imdb_id = b.imdb_id
WHERE
    a.actor < b.actor
GROUP BY a.actor, b.actor
ORDER BY COUNT(*) DESC, a.actor, b.actor 
LIMIT 20 

注意:SQL 在连接时总是创建叉积,即它创建与连接条件匹配的所有可能的记录组合。因此对于 imdb 55r5 (包括 3 个参与者)它首先会生成以下 3 x 3 = 9 对:

John Doe      John Doe
John Doe      Jane Doe
John Doe      Nathan Deer
Jane Doe      John Doe
Jane Doe      Jane Doe
Jane Doe      Nathan Deer
Nathan Deer   John Doe
Nathan Deer   Jane Doe
Nathan Deer   Nathan Deer

然后 WHERE 子句排除所有 a >= b 对,我们得到

John Doe      Nathan Deer
Jane Doe      John Doe
Jane Doe      Nathan Deer

关于sql - SQL 中的别名作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28485262/

相关文章:

java - 非法参数异常 : column '_id' does not exist?

iphone - 从应用程序包读取文本文件

sql - 如何从大表中选择行对?

android - 清理本地数据库甚至应用程序未运行或被杀死

ruby-on-rails-3 - 导入 csv 文件后,在我的 sqlite db 表中创建了额外的行

python - MySQL python 连接器代码中止而没有错误(来自 MySQL 文档的代码)

java - 从 MS Access 中提取数据并输出图表

sql - 微软 Access : Order by calculated field (using alias)

python - 检查sqlite3中是否存在一行?

要以逗号分隔的形式转换的 sql server 列值