如何自行加入表格并获取记录

时间:2019-09-06 09:45:20

标签: mysql

我有一个mysql表“ bf_monthly_bill”,其中每个月来自另一表“ bf_users”的每个用户的数据都按月存储。

我的bf_users表的结构是

id   | display_name
1    | ABC
2    | DEF
3    | GHI
4    | JKL

bf_monthly_bill的结构是

company_id   | package_price  | bill_month
1            | 500            | Jan2k19
2            | 300            | Jan2k19
3            | 900            | Jan2k19
1            | 200            | Feb2k19
3            | 542            | Feb2k19
1            | 500            | Mar2k19
2            | 300            | Mar2k19
3            | 900            | Mar2k19
4            | 200            | Mar2k19

我想要每个帐单月的每个公司名称及其package_price,例如

company_name   | first_month_bill  | second_month_bill |third_month_bill 
ABC            | 500               | 200               |   500 
DEF            | 300               | 0 or Null         |   300
GHI            | 900               | 542               |   900
JKL            | 0 or NUll         | 0 or Null         |   200

我尝试过的是

SELECT bf_users.display_name,first_month.package_price firstt_bill,second_month.package_price second_bill,third_month.package_price third_bill from bf_monthly_bill 
AS first_month 
JOIN bf_monthly_bill AS second_month ON first_month.company_id=second_month.company_id
JOIN bf_monthly_bill AS third_month ON first_month.company_id=third_month.company_id
JOIN bf_users ON bf_users.id=first_month.company_id
Where first_month.bill_month='Jan2k19' AND second_month.bill_month='Feb2k19' AND third_month.bill_month='Mar2k19'

此查询的问题在于,它仅向我提供每月出现的那些公司及其各自的账单

3 个答案:

答案 0 :(得分:3)

您可以尝试使用条件聚合

select display_name,
       sum(case when bill_month='Jan2k19' then package_price end) as first_bill,
       sum(case when bill_month='Feb2k19' then package_price end) as second_bill,
       sum(case when bill_month='Mar2k19' then package_price end) as third_bill
from
(
   SELECT u.display_name,b.package_price,b.bill_month
   from bf_users u inner join bf_monthly_bill b on u.id=b.company_id
)A group by display_name

答案 1 :(得分:3)

  1. 使用LEFT JOIN确保即使您一个月没有账单,您也可以获得完整的公司列表。
  2. 您必须手动或使用脚本创建n列。
  3. 您可以执行简单的联接,不需要子查询。
  4. 使用GROUP BY为每个公司生成一条记录。
  5. 使用CASE WHENIF ELSE创建n列并仅从相关事件行中选择数据。它可以是第一行,也可以是任何行,因此,通过将其他行值设为NULL,因为聚合函数会排除空值,因此可以使用聚合函数来选择数据,即使它位于组的任何一行。
SELECT 
    u.display_name,
    SUM(IF( bill_month='Jan2k19', package_price, NULL)) as first_bill,
    SUM(IF( bill_month='Feb2k19', package_price, NULL)) as second_bill,
    SUM(IF( bill_month='Mar2k19', package_price, NULL)) as third_bill
FROM bf_users u 
LEFT JOIN bf_monthly_bill b on u.id=b.company_id
GROUP BY u.display_name;

答案 2 :(得分:1)

尝试一下::

SELECT bu.name, 
    max(case when (bb.bill_month='Jan2k19') then bb.package_price else NULL end) as 'first_month_bill',
    max(case when (bb.bill_month='Feb2k19') then bb.package_price else NULL end) as 'second_month_bill',
    max(case when (bb.bill_month='Mar2k19') then bb.package_price else NULL end) as 'third_month_bill'
    FROM bf_users bu
    INNER JOIN bf_monthly_bill bb
    ON bu.id = bb.bf_users_id GROUP BY bu.name;

输出::

name    first_month_bill    second_month_bill   third_month_bill
ABC       500                   200                  500
DEF       300                  (null)                300
GHI       900                   542                  900
JKL      (null)                (null)                200

这是 SQLFiddle 演示