0

I'm having a hard time setting up a query(select). Database is not my specialty, so I'm turning to the experts. Let me show what I need.

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

What I need? Example 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

Few notes:

  1. I need this query for MYSQL;
  2. Every Company is linked to at least one server.
  3. I need result grouped by server. So, every company linked to that server must be concatenated by a comma.
  4. If the company has not yet been registered, the value null should be presented.
  5. The sum (page * copie) must be presented as zero or null (I don't care) in the case that there was no printing in the date range.
  6. The percentage should be calculated according to the date range entered and not with all records in the database.
  7. The field date is stored as MYSQL DATE.

Experts, I thank you in advance for your help. I currently solve this problem with at least 03 queries to the database, but I have a conviction that I could do it with just one query.

Added a fiddle. Sorry. Im still learing how to use this. https://www.db-fiddle.com/f/dXej7QCPe9iDopfYd1SfVh/2

Follows the query that more or less represents how far I had arrived. Notice that in the middle of the way 'server4' disappeared because there are no values ​​for it in print in the period searched for him and I am in possession of the total of the period but I cannot calculate the percentage. i'm stuck

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;
Fábio
  • 69
  • 2
  • 6
  • There are different types of JOIN in SQL. Did you try searching for the words ___mysql joins___ ? Here is one [tutorial](https://www.mysqltutorial.org/mysql-join/) Here is [another](https://www.guru99.com/joins.html) There may even be one in your native language. – Abra Oct 02 '20 at 04:34
  • Yes I did. Before I 'give up' I was abble to get it almost done, but there was two problems, at least to me. 1) When there is no company 2) when there in no print in the range of date. – Fábio Oct 02 '20 at 04:49
  • Show source tables as CREATE TABLE + INSERT INTO scripts, not as tables. Or create online fiddle. – Akina Oct 02 '20 at 04:51
  • 1
    I suggest that you [edit] your question and post your SQL along with the result you got and why it is not what you want. You have already posted the result you want to get. – Abra Oct 02 '20 at 04:52
  • Just added the fiddle. – Fábio Oct 02 '20 at 05:19
  • "I was able to get it almost done" Where??? We don't see a single query. – Eric Oct 02 '20 at 05:22
  • Sorry. Maybe a barrier language. But it was in past. months ago. I do not have the query anymore as I gave up. After seeing too much help from here, I'm trying to solve that problem. I ll try it again and as soon I get close, I will post the query. – Fábio Oct 02 '20 at 05:30
  • Please in code questions give a [mre]--cut & paste & runnable code, including smallest representative example input as code; desired & actual output (including verbatim error messages); tags & versions; clear specification & explanation. Give the least code you can that is code that you show is OK extended by code that you show is not OK. (Debugging fundamental.) For SQL that includes DBMS & DDL (including constraints & indexes) & input as code formatted as a table. [ask] Pause work on the overall goal, chop code to the 1st expression not giving what you expect & say what you expect & why. – philipxy Oct 02 '20 at 08:35
  • @philipxy I'm trying to be as clear as possible and, if you can see, this is my first post. I edited the question for everyone who suggested including something to better understand the problem. That said, I don't understand your post, because the `create and insert` are already on the fiddle as well as the desired result is in the description and the query I have advanced so far. – Fábio Oct 02 '20 at 16:47
  • I don't know what is the point of your comment or why you say you don't understand it because you clearly didn't do everything in my comment. However it is a generic post & you have done some of the things in it. PS When you give example data in 2 forms & 2 places we don't know that the version in your post is the version in the link, put everything needed to ask in your post. – philipxy Oct 02 '20 at 23:51

1 Answers1

1

I did this query before you add fiddle, so may be name of column of mine is not same as you. Anyway, this is my solution, hope it help you.

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 and concat by comma, using GROUP_CONCAT .
  2. You can reference this image for JOIN clause. https://i.stack.imgur.com/6cioZ.png
caocon912
  • 26
  • 6
  • 1
    That image doesn't communicate anything until you give a legend to interpret it. And I warn you, that is extremely difficult, because **tables are not sets**. That diagram is abused/misused constantly, people are mistaken that it is helpful. What are the cirlces & what things are in the blue & why are they not elsewhere & why are the circles labelled TableN & why are pairs labelled with joins? See my various comments [on this page](https://stackoverflow.com/q/38549/3404097) where most such diagrams have thankfully been removed & see [this answer](https://stackoverflow.com/a/55642928/3404097). – philipxy Oct 02 '20 at 08:51
  • That's fine. Your query is almost ok with the names. One issue was `'Query Error: Error: ER_BAD_FIELD_ERROR: Unknown column 'cs.id' in 'on clause'`. The column name is `'cs.server'`. Solved. But then I get stuck on `ER_NON_UNIQ_ERROR: Column 'id' in group statement is ambiguous`. I tried to use `ss.id` but no luck. `...not functionally dependent on columns in GROUP BY clause...` – Fábio Oct 02 '20 at 16:35
  • @FbioCassianoNunesdeOliveir I understand, you fixed right. it is my fault.I update my answer in your DB fiddle, check it:https://www.db-fiddle.com/f/dXej7QCPe9iDopfYd1SfVh/4 To fix issues "...not functionally dependent on columns in GROUP BY clause..." you can reference :https://stackoverflow.com/questions/41887460/select-list-is-not-in-group-by-clause-and-contains-nonaggregated-column-inc – caocon912 Oct 02 '20 at 17:42
  • Your query is wonderful and answered exactly what I needed. I will mark your answer as the correct one for the question. Thank you very much. – Fábio Oct 02 '20 at 18:03
  • Glad my answer helps you, please let me know if you still confuse about it. I''ll explain soon. – caocon912 Oct 02 '20 at 18:13