2

これをすべて入力する前に、ここの他のスレッドから、およびGoogleを検索して、これに対する解決策を見つけようとしました。しかし、私は答えを得ることができないようです。私は自分自身をSQLでかなり上手だと思っていますが、この問題をまったく理解できていないようです。

現在、2 つのテーブルがあります。

ここに画像の説明を入力

テーブルに入力するフロントエンドのドロップダウンとして使用されるref_departments.idandの配列を取得しようとしています。この時点で、ドロップダウンなどの作成に技術的な問題はないことを指摘しておくのが最善です。ドロップダウンは Yii フレームワークで構築されており、実際のドロップダウン自体は既に配置されています。私の問題は、ドロップダウンに入力するために必要なデータに戻すための正しい SQL ステートメントを特定することです (Yii の Chtml ヘルパー クラスを使用します)。ref_departments.department_namecompany_department_norm

SELECT私が作成しようとしているステートメントの最初の条件は、テーブルのクエリが(PK) 列の値が列に見つからないref_departments行のみを選択するというものです。これにより、有効なオプションのみがリストに表示されます。このクエリは機能していますが、次のようになります...idcompany_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_normcompany_idフィールドは会社の FK を示します (上記を参照)。これはパラメータとしてクエリに渡され、クエリに条件を追加して、ステートメントがモデルから渡されたものと同じJOIN右側のテーブル ( company_department_name)の行のみと一致するようにします。テスト目的で、SQL ステートメントにハードコードされた整数 1 でこれを機能させようとしています。しかし、私の人生では、これを行う方法がわかりません。company_idcompany_idcompany_id

これを使用して上記のクエリで変更を試みました: -

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

ただし、これは正しいテーブルをまったくフィルタリングしていないようです。

誰でもこれで私を助けることができますか?私よりも経験豊富な SQL ユーザーの方が解決策をすぐに特定できると思いますが、私はこれを解決するために何時間も頭を悩ませてきました!

4

2 に答える 2

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_norm6NF

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

于 2013-02-15T13:54:45.030 に答える
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 でまだ表されていない部門を返しますが、最初のクエリは、どの会社でもまだ表されていない部門を返します。


あなたのコメントについて: サンプル データを考えると、両方の部門会社 1 にあるため、このクエリは company_id 条件を使用するかどうかに違いはありません。

これを 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という名前を付けていますが、結合条件の基になる数値の department_id がありません。そのため、これら 2 つの部門は一致していないと考えられます。

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 に答える