2

次のようなテーブルがあります。

Table1(Contract_id, name, address, contact_no)

そして、次のような別のテーブル、

Table2(Contract_id, approver, owner, authority)

サンプルデータ:

mysql> select * from Table1;
+-------------+-------+---------+------------+
| contract_id | owner | address | contact_no |
+-------------+-------+---------+------------+
|       11111 | XXX   | Madurai | 897161     |
|       12456 | XYZ   | Madras  | 897161     |
|       11111 | XYZ   | Madras  | 897161     |
+-------------+-------+---------+------------+
3 rows in set (0.00 sec)

mysql> select * from Table2;
+-------------+----------+
| contract_id | approver |
+-------------+----------+
|       11111 | YZX      |
|       11112 | YYY      |
+-------------+----------+
2 rows in set (0.00 sec)

すべての contract_ids と一致するデータをこのような条件で取得するクエリを作成しました。

「所有者が「X」、住所が「マッド」、承認者が「YZX」のすべての契約を取得する」

select contract_id,owner,address,approver 
from 
(
    select *
    from Table1 
    where owner like '%X%' 
    and address like '%Mad%'
) t1 
inner join 
(
    select * 
    from Table2 
    where approver = 'YZX'
) t2 using (contract_id);

結果を正しく返しています。しかし問題は、左のテーブルには一致する行が 2 つあり、右のテーブルには一致する行が 1 つしかないことです。したがって、右の表の行は 2 回複製されます。

> +-------------+---------------+-----------+-------------+
> |contract_id  |  owner        | address   | approver    |
> +-------------+---------------+-----------+-------------+
> |11111        | XXX           | Madurai   | YZX         |
> +-------------+---------------+-----------+-------------+
> |11111        | XYZ           | Madras    | YZX         | 
> +-------------+---------------+-----------+-------------+

承認者の値が 2 回重複しています。どうにかしてこのmysql自体を回避できますか? 2 行目の承認者列に null 値が必要です。

編集1:

最後に承認者ごとにグループ化するようにクエリを編集しました。

select contract_id,owner,address,approver 
from 
(
    select contract_id
    from Table1 
    where owner like '%X%' 
    and address like '%Mad%'
) t1 
inner join 
(
    select contract_id 
    from Table2 
    where approver = 'YZX'
) t2 using (contract_id) group by approver;

結果は次のようになりました。

> +-------------+---------------+-----------+-------------+
> |contract_id  |  owner        | address   | approver    |
> +-------------+---------------+-----------+-------------+
> |11111        | XYZ           | Madurai   | YZX         |
> +-------------+---------------+-----------+-------------+

2番目は現在行方不明です。私もそれが欲しい。

編集 2: サンプル データと正確なクエリを追加しました。

EDIT 3:結果を以下のようにフォーマットしたいのですが、

> +-------------+---------------+-----------+-------------+
> |contract_id  |  owner        | address   | approver    |
> +-------------+---------------+-----------+-------------+
> |11111        | XXX           | Madurai   | YZX         |
> +-------------+---------------+-----------+-------------+
> |11111        | XYZ           | Madras    | NULL        | 
> +-------------+---------------+-----------+-------------+

編集 4: 私が望んでいたものを達成しました。以下は私が使用したクエリです。

create temporary table table1 select * 
from 
(
    select *
    from Table1 
    where owner like '%X%' 
    and address like '%Mad%'
) t1 
inner join 
(
    select * 
    from Table2 
    where approver = 'YZX'
) t2 using (contract_id) limit 1;

そしてクエリ、

insert into table1 select contract_id, IF((select count(*) from table1 where owner = t.owner and contract_id = t.contract_id) > 0, NULL, t.contract_id),IF((select count(*) from table1 where address = t.adress and contract_id = t.contract_id) > 0, NULL, t.contract_id),IF((select count(*) from table1 where approver = t.approver and contract_id = t.contract_id) > 0, NULL, t.contract_id)
from 
((
    select *
    from Table1 
    where owner like '%X%' 
    and address like '%Mad%'
) t1 
inner join 
(
    select * 
    from Table2 
    where approver = 'YZX'
) t2 using (contract_id)) t;  
4

3 に答える 3

3

明確にするために、データは複製されていません。2 つのテーブルを結合していcontract_idて、同じ契約 ID が 2 つのレコードに関連付けられているため、承認者が 2 回表示されます。

mysql> select * from Table1;
+-------------+-------+---------+------------+
| contract_id | owner | address | contact_no |
+-------------+-------+---------+------------+
|       11111 | XXX   | Madurai | 897161     | -- contract_id 11111
|       12456 | XYZ   | Madras  | 897161     |
|       11111 | XYZ   | Madras  | 897161     | -- contract_id 11111
+-------------+-------+---------+------------+
3 rows in set (0.00 sec)

mysql> select * from Table2;
+-------------+----------+
| contract_id | approver |
+-------------+----------+
|       11111 | YZX      | -- contract_id 11111
|       11112 | YYY      |
+-------------+----------+
2 rows in set (0.00 sec)

したがって、結果は常に、テーブル 1 からの 2 つのレコードと、テーブル 2 からの 1 つのレコードになります。approver = 'YZX'

別の注意として、クエリを次のように書き直すことを検討してください。

select t1.contract_id, t1.owner, t1.address, t2.approver 
from table1 t1
inner join table2 t2
  on t1.contract_id = t2.contract_id
where t1.owner like '%X%'
  and t1.address like '%Mad%'
  and t2.approver = 'YZX'

あなたのコメントに基づいて、私はあなたが欲しいかもしれないと思い始めていますLEFT JOIN

select t1.contract_id, t1.owner, t1.address, t2.approver 
from table1 t1
left join table2 t2
  on t1.contract_id = t2.contract_id
  and t2.approver = 'YZX'
where t1.owner like '%X%'
  and t1.address like '%Mad%'

デモで SQL Fiddle を参照してください

編集 2: 追加のフィールドに null を使用するよう強制する簡単な方法はありません。行番号を使用して結果を取得できます。

select x.contract_id, 
  x.owner,
  x.address,
  case when (@rownum:=@rownum+1 = 1) then x.approver else null end approver
from 
(
  select t1.contract_id, t1.owner, t1.address, t2.approver
  from table1 t1
  inner join table2 t2
    on t1.contract_id = t2.contract_id
    and t2.approver = 'YZX'
  where t1.owner like '%X%'
    and t1.address like '%Mad%'
) x, (SELECT @rownum:=0) r

デモで SQL Fiddle を参照してください

于 2012-08-10T12:12:03.647 に答える
1

Use DISTINCT clause to avoid duplicates:

SELECT contract_id,owner,address,approver
from (select DISTINCT contract_id
      from Table1 where owner like '%X%' and address like '%Mad%'
     ) t1
     inner join (select contract_id from Table2 where approver = 'YZX') t2
        using (contract_id);
于 2012-08-10T11:45:50.100 に答える
1

複製ではなく、表示すべき内容を正確に表示しています。

表示したいレコードと結果セットから除外したいレコードの基準を説明した場合は、要件を満たすものを作成できる可能性があります。

最初の更新で提供したクエリは、MySQL では構文的に有効かもしれませんが (他の DB では機能しません)、意味が意味不明です。それとも住所=マドラス?

于 2012-08-10T12:11:14.643 に答える