如何修复这个简单的SQL查询?
我有一个包含三个表的数据库:如何修复这个简单的SQL查询?,sql,Sql,我有一个包含三个表的数据库: 用户表 国家表格 城市表 我想编写ANSI SQL,它将允许我获取所有用户数据(即用户详细信息,包括上一所学校的国家名称和他们现在居住的城市名称) 我遇到的问题是,我必须使用自连接,我有点困惑 模式如下所示: CREATE TABLE user_table (id int, first_name varchar(16), last_school_country_id int, city_id int); CREATE TABLE country_table (
- 用户表
- 国家表格
- 城市表
CREATE TABLE user_table (id int, first_name varchar(16), last_school_country_id int, city_id int);
CREATE TABLE country_table (id int, name varchar(32));
CREATE TABLE city_table (id int, country_id int, name varchar(32));
这是我到目前为止提出的查询,但结果是错误的,有时,db引擎(mySQL)会问我是否要显示所有[此处的巨大数字]结果,这让我怀疑我无意中在某处创建了笛卡尔积
有人能解释一下这个SQL语句有什么问题吗?我需要做些什么来修复它
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr, country_table ctry1, country_table ctry2, city_table city
WHERE usr.last_school_country_id=ctry2.id
AND usr.city_id=city.id
AND city.country_id=ctry1.id
AND ctry1.id=ctry2.id;
通常,如果要联接3个表,则会有两个联接语句。始终比要连接的项目数少1个 没关系,我明白你为什么需要加入, 我会继续在代码上工作
SELECT user_table.*, contry_table.*, city_table.* FROM user_table, country_table, city_table WHERE country_table.id = last_school_country_id AND city_id = city_table.id
通常,如果要联接3个表,则会有两个联接语句。始终比要连接的项目数少1个 没关系,我明白你为什么需要加入, 我会继续在代码上工作
SELECT user_table.*, contry_table.*, city_table.* FROM user_table, country_table, city_table WHERE country_table.id = last_school_country_id AND city_id = city_table.id
试试这个。为了清晰起见,我使用了
ANSI
语法编写了它。我假设您可能并不总是拥有usr.city\u id
或usr.last\u school\u country\u id
,因此我使用了左外连接
,这意味着您将始终获得usr
记录
我还删除了和ctry1.id=ctry2.id
,因为这需要用户的当前城市与他们的上一个学校/国家/地区id位于同一个国家/地区,我认为情况并非总是如此
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
left outer join city_table city on usr.city_id=city.id
left outer join country_table ctry1 on city.country_id=ctry1.id
left outer join country_table ctry2 on usr.last_school_country_id=ctry2.id
试试这个。为了清晰起见,我使用了ANSI
语法编写了它。我假设您可能并不总是拥有usr.city\u id
或usr.last\u school\u country\u id
,因此我使用了左外连接
,这意味着您将始终获得usr
记录
我还删除了和ctry1.id=ctry2.id
,因为这需要用户的当前城市与他们的上一个学校/国家/地区id位于同一个国家/地区,我认为情况并非总是如此
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
left outer join city_table city on usr.city_id=city.id
left outer join country_table ctry1 on city.country_id=ctry1.id
left outer join country_table ctry2 on usr.last_school_country_id=ctry2.id
此查询选择城市与其上一所学校位于同一国家/地区的所有用户:
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
JOIN city
ON city.id = usr.city_id
JOIN country_table ctry1
ON ctry1.id = city.country_id
JOIN country_table ctry2
ON ctry2.id = usr.last_school_country_id
WHERE ctry1.id = ctry2.id
它是原始查询的同义词
只要名为id
的所有字段都是主键,此查询返回的记录数就不能超过user\u表中的记录数
确保所有的id
都是主键,并且没有重复项
请运行以下查询:
SELECT COUNT(*)
FROM user_table
SELECT COUNT(*), COUNT(DISTINCT id)
FROM city
SELECT COUNT(*), COUNT(DISTINCT id)
FROM country_table
并将输出张贴在此处?此查询选择其所在城市与其上一所学校位于同一国家/地区的所有用户:
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
JOIN city
ON city.id = usr.city_id
JOIN country_table ctry1
ON ctry1.id = city.country_id
JOIN country_table ctry2
ON ctry2.id = usr.last_school_country_id
WHERE ctry1.id = ctry2.id
它是原始查询的同义词
只要名为id
的所有字段都是主键,此查询返回的记录数就不能超过user\u表中的记录数
确保所有的id
都是主键,并且没有重复项
请运行以下查询:
SELECT COUNT(*)
FROM user_table
SELECT COUNT(*), COUNT(DISTINCT id)
FROM city
SELECT COUNT(*), COUNT(DISTINCT id)
FROM country_table
然后在此处发布输出?您确定ctry1.id=ctry2.id
正确吗?您不需要自联接,也可以使用自联接,但它不会为您提供任何新的功能。你是说“必须使用自连接”,因为这是作业的一部分吗?@MJB:我的SQL可能已经生锈了,但我确实认为我需要一个自连接。原因是学校所在国家/地区和当前所在国家/地区(源自当前城市)可能不同。@Morphase:您能告诉我您希望查询返回什么吗?ctry1.id=ctry2.id对我来说毫无意义。虽然这不是您获得大量行的原因,但它应该只返回最后一个学校所在国家和城市所在国家相同的行。您确定ctry1.id=ctry2.id
正确吗?您不需要自联接,也可以使用自联接,但它不会为您提供任何新内容。你是说“必须使用自连接”,因为这是作业的一部分吗?@MJB:我的SQL可能已经生锈了,但我确实认为我需要一个自连接。原因是学校所在国家/地区和当前所在国家/地区(源自当前城市)可能不同。@Morphase:您能告诉我您希望查询返回什么吗?ctry1.id=ctry2.id对我来说毫无意义。虽然这不是您获得大量行的原因,它应该只返回最后一个学校所在国家和城市所在国家相同的行。如果用户的最后一个学校在不同的国家,情况会怎样?@morphase:我不知道这些情况会怎样:我刚刚重写了您原来的查询。如果您不需要此筛选器,请删除WHERE
子句。如果用户的上一所学校在不同的国家,情况会如何?@morphase:我不知道这些情况会如何:我只是重写了您原来的查询。如果您不需要此筛选器,请去掉WHERE
子句。这是一个很好的示例。我终于有了一个具体的“连接”示例,这对我来说很有意义。我现在明白了。非常感谢。也谢谢你的解释。我已经接受了你的回答。这是一个很好的例子。我终于有了一个具体的“连接”示例,这对我来说很有意义。我现在明白了。非常感谢。也谢谢你的解释。我已经接受了你的回答。