如何解决这个简单的SQL查询?

时间:2010-04-15 13:57:57

标签: sql

我有一个包含三个表的数据库:

  • USER_TABLE
  • country_table
  • city_table

我想编写ANSI SQL,这将允许我获取所有用户数据(即用户详细信息,包括最后一所学校的国家名称和他们现在居住的城市的名称)。

我遇到的问题是我必须使用自我加入,而且我有点困惑。

架构如下所示:

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)会问我是否要显示[HUGE NUMBER HERE]结果 - 这让我怀疑我无意中在某个地方创造了笛卡尔产品。

有人可以解释这个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 个答案:

答案 0 :(得分:1)

试试这个。为清楚起见,我使用ANSI语法编写了它。我假设您可能并不总是usr.city_idusr.last_school_country_id,因此我使用了left outer join,这意味着无论如何您都会获得usr条记录。

我还删除了and ctry1.id=ctry2.id,因为这会要求用户的当前城市与其last_school_country_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 

答案 1 :(得分:0)

通常如果您加入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

答案 2 :(得分:0)

此查询选择城市与其上一所学校位于同一国家/地区的所有用户:

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_table中更多的记录。

确保所有id都是PRIMARY KEY,并且您没有重复项。

请你运行这些查询:

SELECT  COUNT(*)
FROM    user_table

SELECT  COUNT(*), COUNT(DISTINCT id)
FROM    city

SELECT  COUNT(*), COUNT(DISTINCT id)
FROM    country_table

并在此处发布输出?