3

私の問題は次のとおりです。2 つのテーブルがあります。persons人物とチームの場合、チームには存在するがチームには存在しない、role_id = 2 のすべての人物を選択したいと考えています。

テーブルには、一度に1 つのチームしかリードできないチーム リーダーteamsのハッシュが格納されます。チームを作成するとき、現在チームを率いていない人を管理者に表示したいだけです。基本的に、特定のチームのリーダーであるすべての人を除外します。

私の構造は次のとおりです。

mysql> desc persons;
+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| firstname   | varchar(9)  | YES  |     | NULL    |       |
| lastname    | varchar(10) | YES  |     | NULL    |       |
| role_id     | int(2)      | YES  |     | NULL    |       |
| hash        | varchar(32) | NO   | UNI | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

mysql> desc teams;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| name   | varchar(20) | YES  |     | NULL    |                |
| leader | varchar(32) | NO   |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

私の現在のSQLは次のとおりです。

SELECT CONCAT(  `persons`.`firstname` ," ",  `persons`.`lastname` ) AS  `manager`,
`hash` FROM  `persons`
WHERE  `persons`.`role_id` =2 AND  `persons`.`hash` != 
(SELECT  `leader` FROM  `teams` );

後者の SQL クエリは、テーブルteamsにレコードが 1 つしかない場合に機能しますが、別のレコードを追加するとすぐに、MySQL はサブクエリが 2 つのレコードを生成することについて苦情を言います。

WHERE句では、サブクエリの代わりに次のことも試しました。

 WHERE `persons`.`role_id` = 2 AND `persons`.`hash` != `teams`.`leader`

leaderしかし、その後、テーブルに存在しない列について不平を言うteams

ある種のLEFT JOINを使用することも考えていましたが、最適な解決策を思い付くことができませんでした.

どんな助けでも大歓迎です!ありがとう

PS:私のようなシナリオが必要な場合のSQLステートメントは次のとおりです。

DROP TABLE IF EXISTS `teams`;
CREATE TABLE IF NOT EXISTS `teams` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(20) DEFAULT NULL,
   `leader` varchar(32) NOT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

 INSERT INTO `teams` (`id`, `name`, `leader`) VALUES
 (1, 'Team 1', '406a3f5892e0fcb22bfc81ae023ce252'),
 (2, 'Team 2', 'd0ca479152996c8cabd89151fe844e63');


DROP TABLE IF EXISTS `persons`;
CREATE TABLE IF NOT EXISTS `persons` (
  `firstname` varchar(9) DEFAULT NULL,
  `lastname` varchar(10) DEFAULT NULL,
  `role_id` int(2) DEFAULT NULL,
  `hash` varchar(32) NOT NULL,
  PRIMARY KEY `hash` (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `persons` (`firstname`, `lastname`, `role_id`,`hash`) VALUES
('John', 'Doe', 2, '406a3f5892e0fcb22bfc81ae023ce252'),
('Jane', 'Doe', 2, 'd0ca479152996c8cabd89151fe844e63'),
('List', 'Me', 2, 'fbde2c4eeee7f455b655fe4805cfe66a'),
('List', 'Me Too', 2, '6dee2c4efae7f452b655abb805cfe66a');
4

2 に答える 2

5

そのためにサブクエリは必要ありません。LEFT JOIN で十分です。

SELECT
   CONCAT (p.firstname, " ", p.lastname) AS manager
   , p.hash
FROM  persons p
   LEFT JOIN teams t ON p.hash = t.leader
WHERE
   p.role_id = 2
   AND t.id IS NULL -- the trick
于 2012-05-04T17:08:45.487 に答える
3

IN句が必要だと思います。

SELECT CONCAT(  `persons`.`firstname` ," ",  `persons`.`lastname` ) AS  `manager`,
`hash` FROM  `persons`
WHERE  `persons`.`role_id` =2 AND  `persons`.`hash` NOT IN 
(SELECT  `leader` FROM  `teams` );

指摘したように、これは最適ではありません。代わりに結合を行うことができます。

于 2012-05-04T17:00:11.033 に答える