条件LEFT INNER JOIN查询在右表上使用条件SELECT

时间:2013-02-15 13:42:48

标签: mysql sql join conditional

在我输入所有这些之前,我已经尝试过尝试从其他线程中找到解决方案,并通过搜索谷歌。但我似乎无法得到答案。我认为自己对SQL非常好,但我似乎无法解决这个问题。

我目前有两张桌子:

enter image description here

我正在尝试获取ref_departments.idref_departments.department_name的数组,这些数组将用作前端的下拉列表以填充company_department_norm表。在这一点上最好指出我在创建下拉列表时没有技术问题 - 它正在Yii框架中构建,实际的下拉列表已经到位。我的问题是确定正确的SQL语句以恢复我想要填充下拉列表的数据(我将使用Yii的Chtml助手类)。

我要创建的SELECT语句的第一个条件是ref_departments表上的查询只选择id(PK)列中值的行在company_department_norm.department_id列中找不到。这样做只有列表中有效选项可用。我有这个查询工作,它看起来像这样......

SELECT RD.id, RD.department_name FROM ref_departments RD 
LEFT OUTER JOIN company_department_norm CDN
ON (CDN.department_id = RD.id) 
WHERE (CDN.department_id IS NULL)

此后的完整性/数据验证也将在后端(在Yii模型类中)完成。

下一步是我完全坚持的部分。在company_department_norm的Yii模型中,company_id字段表示公司的FK(如上所示)。这将作为参数传递到查询中,以向查询添加其他条件,以便JOIN语句仅匹配右表(company_department_name)上的行company_id是与从模型传递的company_id相同。出于测试目的,我只是尝试使用company_id整数1的硬编码到SQL语句中。然而,对于我的生活,我似乎无法弄清楚如何做到这一点。

我尝试使用以下方法修改上述查询: -

LEFT OUTER JOIN (SELECT * FROM company_department_norm WHERE 
company_department_norm.company_id = 1) CDN

但是,这似乎根本没有过滤掉正确的表格。

任何人都可以帮我吗?我认为比我更有经验的SQL用户能够很快找到解决方案,但是我已经把头发拉了几个小时试图解决这个问题!

2 个答案:

答案 0 :(得分:1)

SELECT RD.id, RD.department_name 
FROM ref_departments RD
WHERE 
    NOT EXISTS (
    SELECT 1 FROM company_department_norm 
    WHERE 
        company_id = 1 
    AND department_id = RD.id
)

PS:您应该考虑删除department_name表的company_department_norm列:6NF

SQLFIDDLE:http://sqlfiddle.com/#!2/553a4/2

答案 1 :(得分:1)

您可以将company_id条件放在ON子句中:

SELECT RD.id, RD.department_name FROM ref_departments RD 
LEFT OUTER JOIN company_department_norm CDN
ON (CDN.department_id = RD.id AND CDN.company_id = 1) 
WHERE (CDN.department_id IS NULL)

这将返回公司1中尚未表示的任何部门,而第一个查询将返回任何公司尚未表示的任何部门。


重新评论:根据您的示例数据,此查询不会显示使用company_id条件之间的任何差异,因为两个部门 代表公司1。

我在MySQL 5.5上测试了它,它运行正常。这是另一个示例,其中包含更多可以更好地展示的数据:

use test;

drop table if exists ref_departments;
create table ref_departments (
 id int primary key,
 department_name varchar(20)
);

insert into ref_departments values
(1, 'Accounts'),
(2, 'HR'),
(3, 'IT');

drop table if exists company_department_norm;
create table company_department_norm (
 id int primary key,
 company_id int,
 department_name varchar(20),
 department_id int
);

insert into company_department_norm values
(1, 1, 'Accounting', 1),
(2, 1, 'HR', 2),
(3, 2, 'Accounts', NULL),
(4, 2, 'HR', NULL),
(5, 2, 'IT', 3);

现在查询不在公司1中的depts,它正确显示“IT”:

SELECT RD.id, RD.department_name FROM ref_departments RD 
LEFT OUTER JOIN company_department_norm CDN
ON (CDN.department_id = RD.id AND CDN.company_id = 1) 
WHERE (CDN.department_id IS NULL);

+----+-----------------+
| id | department_name |
+----+-----------------+
|  3 | IT              |
+----+-----------------+

现在查询不在公司2中的depts。即使公司2 名称帐户和HR,它也没有连接条件所基于的数字department_id。因此它认为这两个部分不匹配。

SELECT RD.id, RD.department_name FROM ref_departments RD 
LEFT OUTER JOIN company_department_norm CDN
ON (CDN.department_id = RD.id AND CDN.company_id = 2) 
WHERE (CDN.department_id IS NULL);

+----+-----------------+
| id | department_name |
+----+-----------------+
|  1 | Accounts        |
|  2 | HR              |
+----+-----------------+

如果你得到其他一些结果,你要么没有按照我的描述使用查询,要么你的数据不像你描述的那样。