情報があまりに少ないので、憶測を交えてとりあえず再現してみました。
SQL
1CREATE TABLE `mgmt_server_backup` (
2 `mgmt_server_backup_id` int(11) NOT NULL,
3 `mst_customer_code` varchar(8) NOT NULL,
4 `job_status` int(11) NOT NULL,
5 `lock_flg` tinyint(1) NOT NULL,
6 `del_flg` tinyint(1) NOT NULL,
7 `expire_date` date DEFAULT NULL
8) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
9
10INSERT INTO `mgmt_server_backup` (`mgmt_server_backup_id`, `mst_customer_code`, `job_status`, `lock_flg`, `del_flg`, `expire_date`) VALUES
11(11, '10000001', 0, 0, 0, '2020-05-24'),
12(22, '3', 0, 0, 0, '2020-05-24');
13
14CREATE TABLE `mgmt_server_backup_share` (
15 `mgmt_server_backup_id` int(11) NOT NULL,
16 `del_flg` tinyint(1) NOT NULL
17) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
18
19INSERT INTO `mgmt_server_backup_share` (`mgmt_server_backup_id`, `del_flg`) VALUES
20(11, 0),
21(33, 0);
22
ここまでで違うところがあれば教えてください。
次に、問題のSQLを実行してみます。
SQL
1SELECT
2 msb.mgmt_server_backup_id AS mgmtServerBackupId,
3 msb.mst_customer_code AS mstCustomerCode
4FROM
5 mgmt_server_backup AS msb,
6 mgmt_server_backup_share AS msbs
7WHERE
8 msb.mgmt_server_backup_id <> msbs.mgmt_server_backup_id
9 AND msbs.del_flg = 0
10 AND msb.job_status = 0
11 AND msb.lock_flg = 0
12 AND msb.del_flg = 0
13 AND msb.expire_date IS NOT NULL
14 AND msb.expire_date >= NOW();
mgmtServerBackupId | mstCustomerCode |
---|
22 | 3 |
11 | 10000001 |
22 | 3 |
ここまで再現できました。
さて、検証するにあたり、SELECTを一旦全選択にしてみます。
また、条件も外してしまいましょう。
SQL
1SELECT
2 *
3FROM
4 mgmt_server_backup AS msb,
5 mgmt_server_backup_share AS msbs
6WHERE
7 1 = 1;
mgmt_server_backup_id | mst_customer_code | job_status | lock_flg | del_flg | expire_date | mgmt_server_backup_id | del_flg |
---|
11 | 10000001 | 0 | 0 | 0 | 2020-05-24 | 11 | 0 |
22 | 3 | 0 | 0 | 0 | 2020-05-24 | 11 | 0 |
11 | 10000001 | 0 | 0 | 0 | 2020-05-24 | 33 | 0 |
22 | 3 | 0 | 0 | 0 | 2020-05-24 | 33 | 0 |
この結果を見る限り、以下の WHERE句のみで絞り込みが実施されていることがわかります。
SQL
1msb.mgmt_server_backup_id <> msbs.mgmt_server_backup_id
他の部分は、必要ないわけではありませんが、今回のレコードでは関係ありません。
すべてのレコードが該当するからです。
SQL
1 AND msbs.del_flg = 0
2 AND msb.job_status = 0
3 AND msb.lock_flg = 0
4 AND msb.del_flg = 0
5 AND msb.expire_date IS NOT NULL
6 AND msb.expire_date >= NOW();
WHERE句の働きを見たうえで再度、WHEREをかけて実行してみます。
SQL
1SELECT
2 *
3FROM
4 mgmt_server_backup AS msb,
5 mgmt_server_backup_share AS msbs
6WHERE
7 msb.mgmt_server_backup_id <> msbs.mgmt_server_backup_id
8 AND msbs.del_flg = 0
9 AND msb.job_status = 0
10 AND msb.lock_flg = 0
11 AND msb.del_flg = 0
12 AND msb.expire_date IS NOT NULL
13 AND msb.expire_date >= NOW();
14
mgmt_server_backup_id | mst_customer_code | job_status | lock_flg | del_flg | expire_date | mgmt_server_backup_id | del_flg |
---|
22 | 3 | 0 | 0 | 0 | 2020-05-24 | 11 | 0 |
11 | 10000001 | 0 | 0 | 0 | 2020-05-24 | 33 | 0 |
22 | 3 | 0 | 0 | 0 | 2020-05-24 | 33 | 0 |
ここからは、shimpei さんがどのような値を取りたいのかによるのでなんとも言えませんが、ここも憶測で以下のように定義してみます。
mgmtServerBackupId と mstCustomerCode の組み合わせが一致するレコードが複数ある場合
mgmtServerBackupId と mstCustomerCode の組み合わせが一致する ということは、mgmtServerBackupId と mstCustomerCode の組み合わせでグループ化することで、実現することが出来ます。
グループ化して、該当のレコードがいくつあるかをカウントする処理まで書いてみましょう。
SQL
1SELECT
2 msb.mgmt_server_backup_id AS mgmtServerBackupId,
3 msb.mst_customer_code AS mstCustomerCode,
4 COUNT(*)
5FROM
6 mgmt_server_backup AS msb,
7 mgmt_server_backup_share AS msbs
8WHERE
9 msb.mgmt_server_backup_id <> msbs.mgmt_server_backup_id
10 AND msbs.del_flg = 0
11 AND msb.job_status = 0
12 AND msb.lock_flg = 0
13 AND msb.del_flg = 0
14 AND msb.expire_date IS NOT NULL
15 AND msb.expire_date >= NOW()
16GROUP BY
17 msb.mgmt_server_backup_id, msb.mst_customer_code;
mgmtServerBackupId | mstCustomerCode | COUNT(*) |
---|
11 | 10000001 | 1 |
22 | 3 | 2 |
一つポイントとして、GROUP BY は WHERE の後に実行されます。
ですので、その結果を WHERE として指定することは出来ません。
この場合は HAVING 句を使います。
SQL
1SELECT
2 msb.mgmt_server_backup_id AS mgmtServerBackupId,
3 msb.mst_customer_code AS mstCustomerCode
4FROM
5 mgmt_server_backup AS msb,
6 mgmt_server_backup_share AS msbs
7WHERE
8 msb.mgmt_server_backup_id <> msbs.mgmt_server_backup_id
9 AND msbs.del_flg = 0
10 AND msb.job_status = 0
11 AND msb.lock_flg = 0
12 AND msb.del_flg = 0
13 AND msb.expire_date IS NOT NULL
14 AND msb.expire_date >= NOW()
15GROUP BY
16 msb.mgmt_server_backup_id, msb.mst_customer_code
17HAVING
18 COUNT(*) > 1;
mgmtServerBackupId | mstCustomerCode |
---|
22 | 3 |
無事に、最初の条件を満たす式がかけました。
ちなみに、”msb.expire_date >= NOW()” を指定している時点でNULLは除かれるので ”msb.expire_date IS NOT NULL” は必要ありません。
また、今回のSQL文は説明重視で書いているため、とても実用的ではありません。
あくまで参考としてください。