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”和地址,例如“Mad”和批准人 = '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);

它正在正确返回结果。但问题是左表有两个匹配行,右表只有一个匹配行。所以右表中的行被复制了两次。

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

批准人值重复两次。我可以以某种方式避免这个mysql本身吗?我想要第二行的批准者列的空值。

编辑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:添加了示例数据和精确查询。

编辑 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

只是为了清楚数据没有重复。由于您要加入两个表,contract_id并且相同的合同 ID 与两条记录相关联,因此您将让批准人出现两次。

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 中的一条记录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:没有简单的方法可以强制它为附加字段使用空值。您可以尝试使用行号来获取结果:

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

使用DISTINCT 子句避免重复:

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 上可能在语法上有效(它不适用于其他数据库),但语义上是乱码——您是如何告诉 DBMS 您真的想排除所有者 = XXX 的情况?或者地址=马德拉斯?

于 2012-08-10T12:11:14.643 回答