至少一个表包含所需值时的 SQL JOIN:这可以在单个查询中实现吗?

Posted

技术标签:

【中文标题】至少一个表包含所需值时的 SQL JOIN:这可以在单个查询中实现吗?【英文标题】:SQL JOIN when at least one table contains the desired value: Can this be achieved in a single query? 【发布时间】:2016-11-14 22:40:46 【问题描述】:

给定一个包含以下表格的 SQL 数据库

TABLE 分支

branch_Id INT 主键

表格部门

dept_Id INT 主键 branch_Id INT

表 Branch_Desc

branch_Id INT 主键 branch_Desc VARCHAR

TABLE Department_Desc

department_Id INT 主键 department_Desc VARCHAR

是否可以返回上表中符合以下要求的值列表:

" 列出至少一个描述(分支或部门)与期望值匹配的所有分支部门、分支描述和部门描述" ?

这里的技巧是查询应该只返回一个匹配的描述,所以如果我们有以下场景:

Branch: 1, Desc: test
Branch: 2, Desc: another
Department: 1, Desc: another
Department: 1, Desc: something else

当期望的值是“另一个”时,查询应该返回:

Branch: 2, Branch Desc: another, Department: 1, Dept Desc: another 

Branch Desc: 'test' 和 Dept Desc 'something else' 不应返回,Branch 1 也不应返回。

假设表结构不能更改,是否可以编写返回正确结果的 SQL 查询?

到目前为止,我得到的最接近的是:

SELECT br.branch_id, bd.branch_desc, de.dept_id, dd.dept_desc
FROM branch br

LEFT JOIN branch_desc bd 
ON bd.branch_id = br.branch_id
AND UPPER(br.branch_desc) = 'value'

JOIN department de 
ON br.branch_id = de.branch_id

LEFT JOIN department_desc dd 
ON de.dept_id = dd.dept_id
AND UPPER(dd.dept_desc) = 'value'

如果至少一个部门包含“值”的描述,则返回正确的值,但是当没有部门包含所需的描述时,则不会返回任何行(即使有与“值”匹配的分支描述)

在这一点上,我认为需要两个单独的查询才能在所有四种可能的情况下获得正确的结果:

    Branch 和 Department 都包含与“值”匹配的描述 只有分支包含与“值”匹配的描述 只有部门包含与“值”匹配的描述 Branch 和 Department 都不包含匹配值的描述

如果这是可能的(而且我感觉一定是这样),我将不胜感激任何朝着正确方向前进的指导。

提前致谢!

【问题讨论】:

你为什么要加入 ON dd.dept_id = dd.dept_id 和 de.branch_id = de.branch_id?你几乎在同一张桌子上加入。可能是你的问题。 如果分支描述是 something 并且该分支的部门名称是 another 并且您正在搜索 another,您是否希望它返回一行? 或者.. 如果“另一个”部门有 15 个分支机构。想要退回所有 15 个分支机构……或者您只需要知道有一个部门匹配。如果您只需要知道有 10 个匹配的部门和 2 个匹配的分支,那么这将是两个单独的查询和一个将结果集放在一起的 UNION……这就是我的意思。 感谢 JNevill。在这种情况下,我需要知道匹配的 10 个部门和 2 个分支机构,所以看起来我需要考虑使用 UNION 【参考方案1】:

当您有一个“匹配这个或那个”的规范时,请考虑在 SQL 中 UNION 类似于逻辑 OR

  SELECT dept_Id, branch_Id,
         Branch_Desc AS branch_or_department_description
    FROM Department
         NATURAL JOIN
         Branch_Desc
  UNION
  SELECT dept_Id, branch_Id,
         department_Desc AS branch_or_department_description
    FROM Department
         NATURAL JOIN
         ( SELECT department_Id AS dept_id, department_Desc FROM Department_Desc ) AS d;

要应用搜索条件 (branch_or_department_description = '<search text>'),您有多种选择,例如创建VIEW,使用派生表等

【讨论】:

正如您所建议的,@JNevill UNION 可用于实现此目的。在我的特殊情况下,由于比较 Oracle 中的 CLOB 出现问题,我不得不使用 UNION ALL(请参阅 (***.com/questions/17732302/…)【参考方案2】:

您在连接中有两个错误。 下面我修复了这些并在 WHERE 子句中使用了 OR。

SELECT br.branch_id, bd.branch_desc, de.dept_id, dd.dept_desc
FROM branch br
INNER JOIN branch_desc bd ON db.branch_id = br.branch_id
INNER JOIN department de ON de.branch_id = br.branch_id 
--note error in your code above and below 
INNER JOIN department_desc dd ON dd.dept_id = de.dept_id
WHERE UPPER(br.branch_desc) = 'value'
   OR UPPER(dd.dept_desc) = 'value';

【讨论】:

您好,添加 OR 会导致查询返回与“值”不匹配的描述。假设 dept_id 5 具有以下描述“值”、“另一个”。在这种情况下,当我只想返回“值”时,查询将在“值”和“另一个”旁边返回 dept_id 5

以上是关于至少一个表包含所需值时的 SQL JOIN:这可以在单个查询中实现吗?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Join on Nearest 小于日期

JOIN列在两个表中具有相同名称时的T-SQL语法缩写?

求SQL语句里面join的用法,求例子及讲解。

SQL连接(join)

SQL表连接查询(inner join(join)full joinleft joinright join)

获取具有任何所需值的组