【问题标题】:SQL - Avoiding Cartesian ProductSQL - 避免笛卡尔积
【发布时间】:2014-02-04 15:37:16
【问题描述】:

我需要从 3 个表、一个列出 Web URL 的表、一个列出可能的类别的表以及一个名为 URL_Categories 的表中编写一条 SQL 语句。 (类似于经典的 Student / Classes / Enrollment SQL Problem)。 URL 和 CATEGORY 的组合使 URL_CATEGORIES。一个 URL 可能有 1 个或“X”个类别,因此 URL_CATEGORY 表中可以有多个行,但 URL 和 CATEGORY 的组合在 URL_CATEGORY 表中是唯一的。适用的 CREATE TABLE 定义是:

CREATE TABLE URL (
  ID AUTOINC,
  SOURCE_DATE DATETIME,
  SITE VARCHAR(30),
 ...
); -186 rows


CREATE TABLE CATEGORY (
  ID AUTOINC,
  CATEGORY_NAME VARCHAR(20),   
);  -- 9 rows

CREATE TABLE URL_CATEGORIES (
  URL_ID INTEGER,
  CAT_ID INTEGER,  
); - 195 rows

简而言之,我想查看所有列。由于 URL_CATEGORIES 有 195 行,我的 OUTPUT 应该有 195 行。对于 URL_CATEGORIES 表中的每一行,选择 URL 表中 URL_CATEGORIES.URL_ID = URL.ID 的所有对应列以及 CATEGORY 表中 URL_CATEGORIES.CAT_ID = CATEGORY.ID 的所有列。

我使用的 SQL 给了我 38025 行,告诉我我有一个笛卡尔问题... SQL 是

select U1."*", C2."*", U3."*"
  from "URL_CATEGORIES" U1 
 inner join "CATEGORY" C2
    on (U1."CAT_ID" = C2."ID"),
      "URL_CATEGORIES" U1 
 inner join "URL" U3
    on (U1."URL_ID" = U3."ID")

我想我需要一个子选择来获取第三张表上的行,而不是一个连接。我需要如何重写我的 SQL?

谢谢

【问题讨论】:

    标签: sql database cartesian-product


    【解决方案1】:

    from 语句中有一个逗号,然后又引用了url_categories,因此得到的是笛卡尔积。查询将此解释为cross join。试试这个:

    select U1.*, C2.*, U3.*
    from URL_CATEGORIES U1 inner join
          CATEGORY C2
          on U1.CAT_ID = C2.ID inner join
          URL U3
          on U1.URL_ID = U3.ID
    

    此查询不需要双引号。

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 2017-05-27
      • 2019-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 2017-05-27
      相关资源
      最近更新 更多