将来自 table 的所有数据与另一个 table 中可能不存在的 where 子句连接

Bring all data from a table with joins with where clause that may not exist in the other table

我很难设置查询(select)。数据库不是我的专长,所以我求助于专家。让我展示我需要的东西。

----companies---     ----company_server-----     -----servers----    -----print------------------------
| id |   name   |    | company | server   |     | id |   name  |    | id |page|copy | date     |server
|----|--------  |    |---------|----------|     |----|-------- |    |----|----|-----|-------------
|  1 | Company1 |1--N|    1    |    1     |N*--1|  1 | Server1 |1--N|  1 |  2 |  3  | 2020-1-11 |   1
|  2 | Company2 |    |    2    |    1     |     |  2 | Server2 |    |  2 |  1 |  6  | 2020-1-12 |   3
|  3 | Company3 |    |    3    |    2     |     |  3 | Server3 |    |  3 |  4 |  5  | 2020-1-13 |   4
                     |    3    |    3     |     |  4 | Server4 |    |  4 |  5 |  3  | 2020-1-15 |   2
                                                                    |  5 |  3 |  4  | 2020-1-15 |   4
                                                                    |  6 |  1 |  2  | 2020-1-16 |   3
                                                                    |  7 |  2 |  2  | 2020-1-16 |   4

我需要什么? 示例 where date between CAST(2020-1-12 AS DATE) AND CAST(2020-1-15 AS DATE) group by servers.id

|       companies       |    server     |        sum                 |  percent
------------------------------------------------------------------------------------
| company1,company2     |    server1    | sum(page*copy) = 0 or null |    0 or NULL
| company3              |    server2    | sum(page*copy) = 15        |    28.30
| company3              |    server3    | sum(page*copy) = 6         |    11.32
| NULL                  |    server4    | sum(page*copy) = 32        |    60.38

几点注意事项:

  1. 我需要此查询 MYSQL;
  2. 每个公司至少链接到一台服务器。
  3. 我需要按服务器分组的结果。因此,链接到该服务器的每个公司都必须用逗号连接。
  4. 如果公司还没有注册,则填null
  5. 在日期范围内没有打印的情况下,总和(页 * 副本)必须显示为零或空(我不在乎)。
  6. 百分比应根据输入的日期范围而不是数据库中的所有记录计算。
  7. 字段日期存储为 MYSQL DATE。

各位专家,在此先感谢各位的帮助。我目前通过至少 03 次查询数据库来解决这个问题,但我坚信我可以通过一次查询来解决。

添加了一个fiddle。对不起。我仍在学习如何使用它。 https://www.db-fiddle.com/f/dXej7QCPe9iDopfYd1SfVh/2

遵循或多或少代表我到达了多远的查询。请注意,中途 'server4' 消失了,因为在搜索他的那段时间里,印刷品中没有它的值,而我拥有那段时间的总数,但我无法计算百分比。 我卡住了

select
*
from 
 (select
      sum(p.copy * p.page) as sum1,
      s.name as s_name,
      s.id as s_id
  from
      print p
  join servers s on s.id = p.server
  where p.date between cast('2020-1-12' as date) and cast('2020-1-15' as date)
  group by s.id) as t1
join company_server cs on cs.server = t1.s_id
right join companies c on c.id = cs.company
cross join(
  select
      sum(p1.copy * p1.page) sum2
  from
      print p1
  where p1.date between cast('2020-1-12' as date) and cast('2020-1-15' as date)
) as c;

我在您添加 fiddle 之前进行了此查询,所以我的列名称可能与您不同。总之,这是我的解决方案,希望对你有帮助。

select group_concat(c.name separator ',') as name_company,
    ss.name, 
    sum_print as sum,
    (sum_print/total) *100 as percentage
    from companies c
    inner join company_server cs on c.id = cs.company 
    right join servers ss on ss.id = cs.id
    left join 
        (
            select server,sum(page*copy) as sum_print, date from print 
            where date between CAST('2020-1-12' AS DATE) AND CAST('2020-1-15' AS DATE)
            group by server
        ) tmp on tmp.server = ss.id 
    cross join  
        (select sum(page*copy) as total from print where date between CAST('2020-1-12' AS DATE) AND CAST('2020-1-15' AS DATE)) tmp2
    group by id
  1. 使用 GROUP_CONCAT .
  2. 按逗号分组和连接
  3. 您可以在 JOIN 条款中引用此图片。 https://i.stack.imgur.com/6cioZ.png