2

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

我目前有两张桌子:

在此处输入图像描述

我正在尝试获取 and 的数组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 模型类中)完成。

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

我试图用上面的查询修改: -

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

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

谁能帮我这个?我可以想象,比我更有经验的 SQL 用户能够很快地识别出解决方案,但我已经花了几个小时试图解决这个问题!

4

2 回答 2

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 的部门,它正确显示“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 中的部门。即使公司 2命名Accounts 和 HR,它也没有连接条件所基于的数字部门 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              |
+----+-----------------+

如果您得到其他结果,您要么没有使用我描述的查询,要么您的数据与您描述的不同。

于 2013-02-15T14:56:29.473 回答
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_namecompany_department_norm6NF

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

于 2013-02-15T13:54:45.030 回答