2

我有 2 个表,见下文 - 配置文件是我的主表/主表

  profiles            invoices
 ____________       ___________________
|id  Name    |     |profileid   paid   |
|============|     |===================|
|1  Abraham  |     |  2         unpaid |
|2  Martin   |     |  3         unpaid |
|3  John     |     |  3         paid   |
|____________|     |___________________|

可以看出,abraham 有 0 张发票,martin 有 1 张未付发票,john 有 2 张发票;1个已付,1个未付。

我想搜索:

  1. 所有带有已付发票的个人资料 (john)
  2. 所有带有未付发票的个人资料 (john & martin)
  3. 所有带有已付和未付发票的个人资料 (john)

我可以很好地完成第 1 步和第 2 步,但我在第 3 步时遇到了问题。

这是我对 1 的查询;

$query = "SELECT DISTINCT profiles.name 
FROM profiles LEFT JOIN invoices ON (profiles.id=invoices.profileid) 
AND (invoices.paid='paid' OR invoices.paid='unpaid')
WHERE
IFNULL(invoices.paid, '') LIKE 'paid';

这是我对 2 的查询;

$query = "SELECT DISTINCT profiles.name 
FROM profiles LEFT JOIN invoices ON (profiles.id=invoices.profileid) 
AND (invoices.paid='paid' OR invoices.paid='unpaid')
WHERE
IFNULL(invoices.paid, '') LIKE 'unpaid';

这是我对 3 的查询;

$query = "SELECT DISTINCT profiles.name 
FROM profiles LEFT JOIN invoices ON (profiles.id=invoices.profileid) 
AND (invoices.paid='paid' OR invoices.paid='unpaid')
WHERE
IFNULL(invoices.paid, '') LIKE 'paid' 
AND IFNULL(invoices.paid, '') LIKE 'unpaid'
;

如前所述,1 和 2 工作正常,但 3 给我 0 结果。任何帮助深表感谢。谢谢

4

3 回答 3

2

您需要选择invoices表 2 次,以便获得有人已付款和未付款的位置。尝试类似的东西 -

SELECT DISTINCT profiles.name 
FROM profiles 
LEFT JOIN invoices i1 ON (profiles.id=i1.profileid) 
AND (i1.paid='paid')
LEFT JOIN invoices i2 ON (profiles.id=i2.profileid) 
AND (i2.paid='unpaid')
WHERE
IFNULL(i1.paid, '') LIKE 'paid' 
AND IFNULL(i2.paid, '') LIKE 'unpaid';

看到这个 sqlfiddle 例子 - http://sqlfiddle.com/#!2/ee4e2/4

于 2013-06-04T22:33:25.280 回答
0

一种可能性是子查询来计算与配置文件关联的不同发票类型

SELECT `profiles`.`name`
FROM `profiles`
WHERE (
  SELECT count( DISTINCT `subinvoices`.`paid` )
  FROM `invoices` AS `subinvoices`
  WHERE `profiles`.`id` = `subinvoices`.`profileid`
    AND (`subinvoices`.`paid` = 'paid' OR `subinvoices`.`paid` = 'unpaid')
) = 2
于 2013-06-04T22:41:26.073 回答
0

最简单的方法是聚合:

select p.*, coalesce(InvoiceInfo, 'NONE')
from profiles p left outer join
     (select profileid,
             (case when sum(paid = 'PAID') > 0 and sum(paid = 'UNPAID') > 0 then 'BOTH'
                   when sum(paid = 'PAID') > 0 then 'PAID-ONLY'
                   when sum(paid = 'UNPAID') > 0 then 'UNPAID-ONLY'
              end) as InvoiceInfo
      from invoices i
     )
     on p.id = i.profileid

这使您可以一次获取所有三种类型的信息。例如,您可以通过以下方式计算每个组中的人数:

select coalesce(InvoiceInfo, 'NONE'), count(*)
from profiles p left outer join
     (select profileid,
             (case when sum(paid = 'PAID') > 0 and sum(paid = 'UNPAID') > 0 then 'BOTH'
                   when sum(paid = 'PAID') > 0 then 'PAID-ONLY'
                   when sum(paid = 'UNPAID') > 0 then 'UNPAID-ONLY'
              end) as InvoiceInfo
      from invoices i
     )
     on p.id = i.profileid
group by coalesce(InvoiceInfo, 'NONE')
于 2013-06-04T23:38:58.057 回答