如何在不使用UNION的情况下在相关表之间执行此查询?

Jer*_*man 2 sql union doctrine

假设我有两个单独的表供我查询.这两个表都与第三个表有关系.如何使用单个非UNION查询查询这两个表?

这是一个理论上的例子.我有一个用户表.该用户可以同时拥有CD和书籍.我希望通过匹配字符串的单个查询找到所有用户的书籍和CD(在此示例中为"awesome").

基于UNION的查询可能如下所示:

SELECT "book" AS model, name, ranking 
 FROM book 
WHERE name LIKE 'Awesome%' 
UNION 
SELECT "cd" AS model, name, ranking 
  FROM cd 
 WHERE name LIKE 'Awesome%' 
ORDER BY ranking DESC
Run Code Online (Sandbox Code Playgroud)

如何在没有UNION的情况下执行这样的查询?如果我从用户到书籍和CD进行简单的左连接,我们最终得到的结果总数等于匹配书籍的匹配数量.是否有GROUP BY或其他一些编写查询的方法来修复此问题?

(编辑:我想避免使用Union方法的原因是因为这实际上是一个DQL查询而且Doctrine不支持UNION.如果没有UNION就没办法做到这一点,我将使用本机SQL路由.此外,真实的查询包含一堆额外的列,在上面的例子中,它们不能很好地相互映射.)

Bil*_*win 5

想想你如何在OO应用程序中对此进行建模.您将创建一个超级类,您可以为书籍和CD扩展,然后您的用户将拥有一组Collectibles.该集合中的任何给定对象都是书籍或CD(或其他类型的收藏品),但它只具有这些子类型中的一种.

您可以通过创建与超类型对应的来执行与SQL类似的操作:

CREATE TABLE Collectibles (
  collectible_id SERIAL PRIMARY KEY,
  user_id        INT NOT NULL,
  FOREIGN KEY (user_id) REFERENCES Users(user_id)
);
Run Code Online (Sandbox Code Playgroud)

然后每个子类型都包含一个引用它以使其可收集:

CREATE TABLE Books (
  book_id   BIGINT UNSIGNED PRIMARY KEY
  book_name VARCHAR(100) NOT NULL,
  FOREIGN KEY (book_id) REFERENCES Collectibles(collectible_id)
);

CREATE TABLE CDs (
  cd_id   BIGINT UNSIGNED PRIMARY KEY
  cd_name VARCHAR(100) NOT NULL,
  FOREIGN KEY (cd_id) REFERENCES Collectibles(collectible_id)
);
Run Code Online (Sandbox Code Playgroud)

现在您可以进行查询,并确保您不会获得笛卡尔积:

SELECT u.*, COALESCE(b.book_name, d.cd_name) AS media_name
FROM Users u
JOIN Collectibles c ON (u.user_id = c.user_id)
LEFT OUTER JOIN Books b ON (b.book_id = c.collectible_id)
LEFT OUTER JOIN CDs d ON (d.cd_id = c.collectible_id);
Run Code Online (Sandbox Code Playgroud)