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路由.此外,真实的查询包含一堆额外的列,在上面的例子中,它们不能很好地相互映射.)
想想你如何在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)