2

複雑な除外 SQL クエリを作成するのに助けが必要です (少なくとも私にとっては)。最初に、ここで要件とクエリについて説明します...

言う

  1. ユーザーの名前とuser_idsが維持されるテーブル「my_users」があります。

  2. スキル名と対応する skill_id を維持するテーブル "my_skills" があります。

  3. ユーザーとそれに対応するskill_idsが維持されるテーブル「my_users_skills」があります。

  4. 会社名と対応する company_ids を保持するテーブル「my_companies」があります。

  5. 雇用者ユーザーIDと雇用者会社IDを含むテーブル「my_employer_profile」があります

  6. テーブル "my_users_blocked_companies" があり、ユーザー ID と対応するブロックされた会社 ID が含まれています。「my_users_blocked_companies」テーブルの目的は、ブロックされた企業としてユーザーのために 1 つ以上の企業を維持することです。

ある会社の人事担当者がユーザーを検索した場合、その会社 (人事が勤務している会社) をブロックされた会社として設定したユーザーは検索結果に表示されません。

SQLクエリを取得しましょう

1.

DROP TABLE IF EXISTS my_users;

CREATE TABLE my_users
(
user_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(20) NOT NULL UNIQUE,
age int NULL
)


INSERT INTO my_users VALUES
(1, "John", 20),
(2, "Kelly", 25),
(3, "Xavier", 50),
(4, "Krishna", 40);

2.

DROP TABLE IF EXISTS my_skills;

CREATE TABLE my_skills
(
skill_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
skill varchar(20) NOT NULL UNIQUE
);


INSERT INTO my_skills VALUES
(1, "MySql"),
(2, "Php"),
(3, "Linux"),
(4, "Java");

3.

DROP TABLE IF EXISTS my_users_skills;

CREATE TABLE my_users_skills
(
user_id int NOT NULL,
skill_id int NOT NULL
);

INSERT INTO my_users_skills VALUES
(1,2),
(1,4),
(2,1),
(2,4),
(3,2),
(3,3);

4.

DROP TABLE IF EXISTS my_companies;

CREATE TABLE my_companies
(
company_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
company varchar(20) NOT NULL UNIQUE
);


INSERT INTO my_companies VALUES
(1, "Motorola"),
(2, "Logica"),
(3, "Microsft"),
(4, "Texas Instruements");

5.

DROP TABLE IF EXISTS my_employer_profile;

CREATE TABLE my_employer_profile
(
user_id int NOT NULL,
comp_id int NOT NULL
);

INSERT INTO my_employer_profile VALUES
(4,1),

「クリシュナ」がモトローラ社の従業員であることは明らかです。

6.

DROP TABLE IF EXISTS my_users_blocked_companies;

CREATE TABLE my_users_blocked_companies
(
user_id int NOT NULL,
comp_id int NOT NULL
);

INSERT INTO my_users_blocked_companies VALUES
(1,1),
(1,4),
(2,4)

ここで、John が Motorola と Texas Instruments をブロックされた企業として設定したことがはっきりとわかります。また、kelly は Texas Instruments をブロック会社として設定しました。

ここで、クリシュナがスキル セット「java」、「mysql」を持つユーザーを検索している場合、次の 2 つのケースが考えられます。

ケース1

ブロックされた会社を考慮しない検索結果は、John と Kelly のレコードを取得します。

この場合の SQL クエリは次のとおりです。

SELECT x.name
, GROUP_CONCAT(DISTINCT y2.skill ORDER BY y2.skill) skills
FROM my_users x
JOIN my_users_skills xy1
ON xy1.user_id = x.user_id
JOIN my_skills y1
ON y1.skill_id = xy1.skill_id
AND y1.skill IN ('java','mysql')
JOIN my_users_skills xy2
ON xy2.user_id = xy1.user_id
JOIN my_skills y2
ON y2.skill_id = xy2.skill_id
GROUP
BY x.user_id; 

ケース 2

そして、ジョンがモトローラをブロックされた会社として設定し、クリシュナがモトローラの出身であるため、ブロックされた会社を考慮した検索結果は、ケリーのレコードを取得します

この場合、私はかなり苦労しましたが、正しいクエリを書くことができませんでした。

4

1 に答える 1

1

次のように実行できます。

SELECT x.name , GROUP_CONCAT(DISTINCT y2.skill ORDER BY y2.skill) skills 
   FROM my_users x 
   JOIN my_users_skills xy1 
       ON xy1.user_id = x.user_id 
   JOIN my_skills y1 
       ON y1.skill_id = xy1.skill_id AND y1.skill IN ('java','mysql') 
   JOIN my_users_skills xy2 
       ON xy2.user_id = xy1.user_id 
   JOIN my_skills y2 
       ON y2.skill_id = xy2.skill_id 
   GROUP BY x.user_id 
       HAVING x.user_id NOT IN (
         SELECT bc.user_id FROM my_users_blocked_companies bc 
         LEFT JOIN my_companies c ON bc.comp_id = c.company_id
         WHERE c.company IN ('Motorola')
       );

ここでsqlfiddleを実行

于 2012-11-28T23:09:27.363 に答える