【问题标题】:Multiple Join Showing More than One Record显示多条记录的多重连接
【发布时间】:2016-05-29 21:52:50
【问题描述】:

我有两个表 - 类似于下面。第一个表存储有关每个作业的信息:

+--------+------------+
| JOB_ID |  JOB_NAME  |
+--------+------------+
|        |            |
| 1      | Test Job 1 |
|        |            |
| 2      | Test Job 2 |
|        |            |
| 3      | Test Job 3 |
|        |            |
| 4      | Test Job 4 |
|        |            |
| 5      | Test Job 5 |
|        |            |
| 6      | Test Job 6 |
|        |            |
| 7      | Test Job 7 |
+--------+------------+

第二个表,存储与每个工作相关的一个或多个“主题”:

+------------+--------+------------------+
| SUBJECT_ID | JOB_ID |   SUBJECT_NAME   |
+------------+--------+------------------+
|            |        |                  |
| 1          | 1      | Test Subject #1  |
|            |        |                  |
| 2          | 1      | Test Subject #2  |
|            |        |                  |
| 3          | 1      | Test Subject #3  |
|            |        |                  |
| 4          | 2      | Test Subject #4  |
|            |        |                  |
| 5          | 3      | Test Subject #5  |
|            |        |                  |
| 6          | 3      | Test Subject #6  |
|            |        |                  |
| 7          | 3      | Test Subject #7  |
|            |        |                  |
| 8          | 4      | Test Subject #8  |
|            |        |                  |
| 9          | 5      | Test Subject #9  |
|            |        |                  |
| 10         | 6      | Test Subject #10 |
|            |        |                  |
| 11         | 7      | Test Subject #11 |
|            |        |                  |
| 12         | 7      | Test Subject #12 |
|            |        |                  |
| 13         | 7      | Test Subject #13 |
+------------+--------+------------------+

目前,我有一条 SQL 语句,显示所有工作,以及两个字段中的前两个“主题”,结果如下:

+--------+------------+------------------+------------------+
| JOB_ID |  JOB_NAME  |    SUBJECT 1     |    SUBJECT 2     |
+--------+------------+------------------+------------------+
|        |            |                  |                  |
| 1      | Test Job 1 | Test Subject #1  | Test Subject #2  |
|        |            |                  |                  |
| 2      | Test Job 2 | Test Subject #4  |                  |
|        |            |                  |                  |
| 3      | Test Job 3 | Test Subject #5  | Test Subject #6  |
|        |            |                  |                  |
| 4      | Test Job 4 | Test Subject #8  |                  |
|        |            |                  |                  |
| 5      | Test Job 5 | Test Subject #9  |                  |
|        |            |                  |                  |
| 6      | Test Job 6 | Test Subject #10 |                  |
|        |            |                  |                  |
| 7      | Test Job 7 | Test Subject #11 | Test Subject #12 |
+--------+------------+------------------+------------------+

这是由以下 SQL 产生的:

SELECT   job.job_id as 'Id',  
job.job_name as 'JobName', 
Subjects1.Subject as 'Subject 1', 
Subjects2.Subject as 'Subject 2', 
LEFT JOIN job_Subjects as Subjects1 ON Subjects1.job_id = job.job_id AND Subjects1.Subject_id = (SELECT Subject_id FROM job_Subjects WHERE job_Subjects.job_id = job.job_id ORDER BY job_Subjects.Subject_index LIMIT 1) 
LEFT JOIN job_Subjects as Subjects2 ON Subjects2.job_id = job.job_id AND Subjects2.Subject_id = (SELECT Subject_id FROM job_Subjects WHERE job_Subjects.job_id = job.job_id ORDER BY job_Subjects.Subject_index LIMIT 1,1) 

但是,我还需要搜索主题的名称(job_subjects.subject 字段)。

我尝试了以下方法:

  • 添加了“WHERE job_subjects.subject LIKE '%Test Job 3%'” - 但是我收到以下错误:“'where 子句'中的未知列 'job_subjects.subject'”
  • 添加了另一个连接“LEFT JOIN job_subjects as SearchSubjects ON SearchSubjects .job_id = job.job_id”,然后添加了“WHERE SearchSubjects.subject LIKE '%Test Job 3%'”但是我似乎得到了多个 JOB 结果(其中,它似乎会为其找到的每个主题结果生成一个作业行结果)。

如何搜索主题表,同时保持两个连接的原样?

【问题讨论】:

    标签: mysql sql join


    【解决方案1】:

    MySQL 有一个很好的扩展,你可以使用HAVING 子句来做你想做的事。首先,我建议您对列名使用反引号 - 或使用不需要转义的名称。

    SELECT job.job_id as Id, job.job_name as JobName, 
           Subjects1.Subject as Subject1, 
           Subjects2.Subject as Subject2
    FROM ?? LEFT JOIN
         job_Subjects Subjects1
         ON Subjects1.job_id = job.job_id AND
            Subjects1.Subject_id = (SELECT Subject_id FROM job_Subjects WHERE job_Subjects.job_id = job.job_id ORDER BY job_Subjects.Subject_index LIMIT 1
                                   ) LEFT JOIN
         job_Subjects Subjects2
         ON Subjects2.job_id = job.job_id AND
            Subjects2.Subject_id = (SELECT Subject_id FROM job_Subjects WHERE job_Subjects.job_id = job.job_id ORDER BY job_Subjects.Subject_index LIMIT 1,1
                                   ) 
    HAVING Subject1 LIKE '%Test Job 3%';
    

    您也可以使用子查询来执行此操作。那将是更传统的方法。但是,MySQL 会实现子查询,从而导致一些性能开销。

    【讨论】:

    • 不错的答案!一个问题...您说子查询将是额外的开销。这与您加入的子查询有什么不同吗?它几乎就像一个依赖子查询,除了你限制它。不确定我是否完全理解如何提高性能。
    • 谢谢 Gordon - 它实际上给了我想要的结果(太棒了),但是上面的查询需要大约 43 秒来执行(以前大约 1 - 2 秒)......我想我是否需要继续尝试改进/优化查询?
    • @AndrewMilici 。 . .您可能想问另一个关于如何加快速度的查询。
    • @JohnRuddell 。 . . join 上的子查询只返回一行,所以具体化没什么大不了的。它们效率低下的原因不同。
    猜你喜欢
    • 2013-08-27
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2015-09-25
    • 2012-04-24
    • 2016-02-06
    • 2023-04-10
    相关资源
    最近更新 更多