不存在,返回空结果集

时间:2018-10-06 08:53:31

标签: mysql

数据库包含4个表格-费用,月份,客户,发票。

表格-month(费用期)

(包含1月至12月的所有月份,此处仅两个月,以简化问题)

id  |   ttl |   year
====================
1   |   Jan |   1
2   |   Feb |   1

表格-fee(费用名称)

id  |   ttl     |   year
========================
1   |   Annual  |   1
2   |   Monthly |   1
3   |   Extra   |   1

表格-customer(客户名称)

id  |   ttl     |   year
========================
1   |   Rahul   |   1

表格-invoice(发票列表)

id  |   cid |   fid |   mid
===========================
1   |   1   |   1   |   1
2   |   1   |   2   |   1

在12个月内,必须每月每个月支付月费和额外费用。

但是年费是一次支付,在不固定的月份支付,可以在1月或12月或该月之间的任何月份支付。

现在,我的要求是显示尚未准备好发票的相关月份的每笔费用(不在发票表中的每月费用名称),只需列出未付款的月份费用列表。所以我将LEFT JOINNULL

一起使用
SELECT
    customer.id AS cid,
    month.id AS mid,
    fee.id AS fid,
    month.ttl AS mth,
    fee.ttl AS fee,
FROM
    fee
LEFT JOIN
    month ON month.year = fee.year
LEFT JOIN
    customer ON customer.year = fee.year
LEFT JOIN
    invoice ON invoice.mid = month.id AND invoice.fid = fee.id
WHERE
    customer.id=1 AND invoice.fid IS NULL

结果是-

cid |   mid |   fid |   mth |   fee 
=======================================
1   |   1   |   3   |   Jan |   Extra
1   |   2   |   1   |   Feb |   Annual  
1   |   2   |   2   |   Feb |   Monthly 
1   |   2   |   3   |   Feb |   Extra

但是,我想要的是-如上所述,年费仅支付一次,因此,如果是“年鉴”发票,则应排除此费用(如果不包括在内)以得到以下结果

cid |   mid |   fid |   mth |   fee 
=======================================
1   |   1   |   3   |   Jan |   Extra
1   |   2   |   2   |   Feb |   Monthly 
1   |   2   |   3   |   Feb |   Extra

因为年费已在1月支付。

所以我要编辑条件

WHERE
    customer.id=1 
AND 
    invoice.fid IS NULL 
AND 
    NOT EXISTS (select invoice.fid from invoice where invoice.fid = 1 AND invoice.cid=customer.id)

但是MySQL返回了一个空结果集

1 个答案:

答案 0 :(得分:0)

  • 您缺少客户invoicecustomerid表之间的JOIN条件。
  • 由于在monthfee表之间进行联接,因此对于fee.ttl = 'Annual'而言,您将获得多行。
  • 一种方法是将其分为两个不同的SELECT查询,并使用UNION ALL。首选查询考虑fee.ttl != 'Annual'。第二选择仅考虑fee.ttl = 'Annual'的情况。在第二个Select查询中,我们不与month表联接,因此避免了“ Annual”的多个行。
  • 请注意,我在ttl字段中匹配了“ Annual”,而不是fid。似乎由于年份不同,“年度”将有多个fid值。因此,检查fid = 1仅用于year = 1的目的。
  • 还请注意,由于您的联接表排序,我已将您的某些Left联接更改为Inner联接。

尝试以下操作:

(SELECT
    customer.id AS cid,
    month.id AS mid,
    fee.id AS fid,
    month.ttl AS mth,
    fee.ttl AS fee 
FROM
    fee
INNER JOIN
    month ON month.year = fee.year
INNER JOIN
    customer ON customer.year = fee.year
LEFT JOIN
    invoice ON invoice.mid = month.id AND 
               invoice.fid = fee.id AND 
               invoice.cid = customer.id 
WHERE
    customer.id = 1 AND 
    fee.ttl != 'Annual' AND 
    invoice.fid IS NULL
)

UNION ALL 

(SELECT
    customer.id AS cid,
    '' AS mid,
    fee.id AS fid,
    '' AS mth,
    fee.ttl AS fee 
FROM
    fee 
INNER JOIN
    customer ON customer.year = fee.year
LEFT JOIN
    invoice ON invoice.fid = fee.id AND 
               invoice.cid = customer.id 
WHERE
    customer.id = 1 AND 
    fee.ttl = 'Annual' AND 
    invoice.fid IS NULL
)