对允许 null 的多对多关系使用左外连接

发布于 2024-12-21 09:53:07 字数 1137 浏览 3 评论 0原文

我在 MySQL 中有一个多对多表关系,涉及三个表:ticketsticket_solutionssolutions。 (一个工单可能有多个解决方案,并且解决方案适用于多个工单。)

以下是简化的表结构:(

tickets    ticket_solutions    solutions
-----      -----               -----
id         ticket_id           id
           solution_id         solution

在此示例中,除 solutions.solution 外,所有字段均为 INT > 这是 VARCHAR。)由于有些问题尚未完成,他们可能没有任何解决方案。

我编写了以下查询:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions
FROM tickets t
LEFT JOIN ticket_solutions tsol ON (tsol.ticket_id = t.id)
LEFT JOIN solutions sol ON (tsol.solution_id = sol.id)
GROUP BY t.id DESC;

我的问题在于第二个LEFT JOIN。在给定工单的链接器表 (ticket_solutions) 中存在条目的任何情况下,总是solutions 中存在匹配的记录。但是,如果我尝试使用 INNER JOIN 代替,我将不再收到缺少解决方案的票证。

在我看来,NULL 值唯一出现的情况是在tickets 和链接器表之间的关系中。 (还没有任何解决方案。)

我必须在链接器表和解决方案之间使用LEFT JOIN,即使不会有NULL值在那个特定的关系中?

如果不是,推荐的查询结构是什么?

I have a many-to-many table relationship in MySQL involving three tables: tickets, ticket_solutions, and solutions. (A ticket may have multiple solutions, and solutions apply to multiple tickets.)

Here are the table structures, simplified:

tickets    ticket_solutions    solutions
-----      -----               -----
id         ticket_id           id
           solution_id         solution

(In this example, all fields are INT except solutions.solution which is VARCHAR.) Since some tickets aren't completed, they may not have any solutions.

I've written the following query:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions
FROM tickets t
LEFT JOIN ticket_solutions tsol ON (tsol.ticket_id = t.id)
LEFT JOIN solutions sol ON (tsol.solution_id = sol.id)
GROUP BY t.id DESC;

My question lies with the second LEFT JOIN. In any situation where an entry exists in the linker table (ticket_solutions) for a given ticket, there will always be a record to match in solutions. However if I try to use an INNER JOIN instead, I no longer get tickets which lack solutions.

To my thinking, the only time NULL values will occur is in the relationship between tickets and the linker table. (Ticket without any solutions yet.)

Must I use a LEFT JOIN between the linker table and solutions even though there won't be NULL values in that particular relationship?

If not, what is the recommended query structure?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡水深流 2024-12-28 09:53:07

试试这样:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions
    FROM tickets t
        LEFT JOIN ticket_solutions tsol 
            INNER JOIN solutions sol 
                ON (tsol.solution_id = sol.id)
            ON (tsol.ticket_id = t.id)
    GROUP BY t.id DESC;

Try it this way:

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ') solutions
    FROM tickets t
        LEFT JOIN ticket_solutions tsol 
            INNER JOIN solutions sol 
                ON (tsol.solution_id = sol.id)
            ON (tsol.ticket_id = t.id)
    GROUP BY t.id DESC;
心房的律动 2024-12-28 09:53:07

在原始 SQL 中,您将票证左连接到ticket_solutions,然后将结果视图内连接到解决方案,这将抑制没有相应解决方案的行。

在 Joe Stefanelli 的回答中,也可以写为

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ')
FROM tickets t
LEFT JOIN
    (SELECT ticket_solutions.ticket_id AS id, solutions.solution AS solution
     FROM ticket_solutions tsol 
     INNER JOIN solutions ON ticket_solutions.solution_id=solutions.id
    ) AS sol ON t.id=sol.id

首先将 Ticket_solutions 内连接到解决方案,然后将结果视图左连接到票证,从而不抑制空票证。

In your original SQL you left-join tickets to ticket_solutions, then inner-join the resulting view to solutions, which will supress rows without a corresponding solution.

In Joe Stefanelli's answer, which could also be written as

SELECT t.id, GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', ')
FROM tickets t
LEFT JOIN
    (SELECT ticket_solutions.ticket_id AS id, solutions.solution AS solution
     FROM ticket_solutions tsol 
     INNER JOIN solutions ON ticket_solutions.solution_id=solutions.id
    ) AS sol ON t.id=sol.id

you first inner-join ticket_solutions to solutions, then left-join the resulting view to tickets, thus NOT supressing the empty tickets.

救赎№ 2024-12-28 09:53:07

乔·斯特凡内利的回答绝对正确。
只是想补充一点,您可以使用

IFNULL(GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', '), '')

空字符串而不是空值。

然而,由于关于同一问题的其他一些讨论令人困惑,所以也想链接这个小提琴: http://www.sqlfiddle.com/#!2/54c6f/3/0

The answer of Joe Stefanelli is absolutely right.
Just wanted to add that you can use

IFNULL(GROUP_CONCAT(DISTINCT sol.solution SEPARATOR ', '), '')

to have an empty string instead of nulls.

However, since some other discussions about the same problem are confusing, just wanted to link this fiddle as well: http://www.sqlfiddle.com/#!2/54c6f/3/0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文