简体   繁体   中英

Mysql create a table out of some data

I have a database full of invoices. In the end of the year I want to do a review of the year. I want the review to look similar to a this picture:

在此处输入图片说明

This is a example of the data I have...

在此处输入图片说明

Here is the query I have done until this moment. If there someone who can help I would appreciate it.

SELECT invID, invDate, craftArr, vesselTotal, craftGT
FROM company, agents, vessels, invoice
WHERE invoice.status =  '0'
AND invoice.craftArr >  '2014-01-01'
AND invoice.craftArr <  '2014-12-31'
AND invoice.invCraft = vessels.craftID
AND vessels.craftComp = company.compID
AND company.compAgent = agents.agentID
ORDER BY craftArr ASC

I'll try to give you a clue, how to achieve your goal.

  1. Loop through ranges of GT:

    1.1. Use this query to collect totals for each month in given range. Query will give you list of amounts for current row.

    NOTE. You pass two variables from your PHP script for GT range start and end.

    SELECT MONTH(craftArr) as monthNumber, sum(vesselTotal) as total FROM company, agents, vessels, invoice WHERE invoice.status = '0' AND invoice.craftArr > '2014-01-01' AND invoice.craftArr < '2014-12-31' AND invoice.invCraft = vessels.craftID AND vessels.craftComp = company.compID AND company.compAgent = agents.agentID AND craftGT between ($START_CURRENT RANGE, $END_CURRENT_RANGE) group by MONTH(craftArr) ORDER BY monthNumber ASC

    1.2. Set $total variable to 0.

    1.3. Loop through months and results of query using one loop:

    NOTE. Amounts are absent if there are no invoices for some months. You need to handle it, while iterating ( monthNumber can be used for this).

    1.3.1. Output amount in appropriate cell or 0 if no result for this month present.

    1.3.2. Increase $total by current amount

    1.4. Output total for the current row

You just want conditional aggregation. The place to start is by fixing your query, to use proper joins.

Here is a sketch of what it would look like:

SELECT craftGT,
       sum(case when month(craftArr) = 1 then vesselTotal else 0 end) as Jan,
       sum(case when month(craftArr) = 2 then vesselTotal else 0 end) as Feb,
       . . .
       sum(case when month(craftArr) = 12 then vesselTotal else 0 end) as Dec,
       sum(vesselTotal) as Total
FROM company join
     agents
     on company.compAgent = agents.agentID join
     vessels
     on vessels.craftComp = company.compID join
     invoice
     on invoice.invCraft = vessels.craftID
WHERE invoice.status =  '0' AND
      invoice.craftArr >  '2014-01-01' AND
      invoice.craftArr <  '2014-12-31'
GROUP BY craftGT;

You seem to want the craftGT placed into ranges. It is unclear what the details look like, but you would do this with a case :

SELECT (case when CraftGT BETWEEN 0 and 1000 THEN '0-1000'
             when CraftGT BETWEEN 1001 and 1999 THEN 1000-1999'
             . . .
        end) as craftGTRange
. . .
GROUP BY craftGTRange

Two things should be immediately clear from the example posted below. The first is that PHP is not my strong point!! The second is that, even so, it's surprisingly easy to construct the required output! This concept can be expanded to something like a datagrid, which brings much greater flexibility.

Note that for ease of comprehension, I've simplified the 'GT brackets'.

The data set...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
 (invID INT NOT NULL AUTO_INCREMENT PRIMARY KEY
 ,InvDate DATE NOT NULL
 ,craftArr DATETIME NOT NULL
 ,vesselTotal DECIMAL(6,2) NOT NULL
 ,craftGT INT NOT NULL
 );

INSERT INTO my_table VALUES
(23 ,'2014-02-01','2014-01-31 23:10:00', 595.07, 13992),
(24 ,'2014-02-02','2014-02-02 03:20:00', 956.08, 33933),
(25 ,'2014-02-05','2014-02-05 00:00:00', 952.06, 52926),
(26 ,'2014-02-05','2014-02-05 00:35:00', 637.38, 30998),
(50 ,'2014-02-05','2014-02-05 01:00:00',1196.25, 42289),
(28 ,'2014-02-06','2014-02-06 00:40:00', 480.64, 24344),
(30 ,'2014-02-06','2014-02-06 15:10:00', 246.7 , 8500),
(31 ,'2014-02-07','2014-02-06 23:30:00',2082.69, 71304),
(34 ,'2014-02-07','2014-02-07 00:10:00',1429.2 , 77499),
(32 ,'2014-02-07','2014-02-07 00:40:00', 557.34, 26302);

SELECT * FROM my_table;
+-------+------------+---------------------+-------------+---------+
| invID | InvDate    | craftArr            | vesselTotal | craftGT |
+-------+------------+---------------------+-------------+---------+
|    23 | 2014-02-01 | 2014-01-31 23:10:00 |      595.07 |   13992 |
|    24 | 2014-02-02 | 2014-02-02 03:20:00 |      956.08 |   33933 |
|    25 | 2014-02-05 | 2014-02-05 00:00:00 |      952.06 |   52926 |
|    26 | 2014-02-05 | 2014-02-05 00:35:00 |      637.38 |   30998 |
|    28 | 2014-02-06 | 2014-02-06 00:40:00 |      480.64 |   24344 |
|    30 | 2014-02-06 | 2014-02-06 15:10:00 |      246.70 |    8500 |
|    31 | 2014-02-07 | 2014-02-06 23:30:00 |     2082.69 |   71304 |
|    32 | 2014-02-07 | 2014-02-07 00:40:00 |      557.34 |   26302 |
|    34 | 2014-02-07 | 2014-02-07 00:10:00 |     1429.20 |   77499 |
|    50 | 2014-02-05 | 2014-02-05 01:00:00 |     1196.25 |   42289 |
+-------+------------+---------------------+-------------+---------+
10 rows in set (0.00 sec)

SELECT FLOOR(craftgt/1000)*1000 GT
     , MONTH(craftarr) month
     , SUM(vesseltotal) income 
  FROM my_table 
 WHERE craftarr BETWEEN '2014-01-01' AND '2015-01-01' 
 GROUP 
    BY FLOOR(craftgt/1000)*1000
     , MONTH(craftarr);
+-------+-------+---------+
| GT    | month | income  |
+-------+-------+---------+
|  8000 |     2 |  246.70 |
| 13000 |     1 |  595.07 |
| 24000 |     2 |  480.64 |
| 26000 |     2 |  557.34 |
| 30000 |     2 |  637.38 |
| 33000 |     2 |  956.08 |
| 42000 |     2 | 1196.25 |
| 52000 |     2 |  952.06 |
| 71000 |     2 | 2082.69 |
| 77000 |     2 | 1429.20 |
+-------+-------+---------+

The php...

<?php
include('path/to/connection/scr.ipt');

$query = "
SELECT FLOOR(craftgt/1000)*1000 GT
     , MONTH(craftarr) month
     , SUM(vesseltotal) income
  FROM my_table
 WHERE craftarr BETWEEN '2014-01-01' AND '2015-01-01'
 GROUP
    BY FLOOR(craftgt/1000)*1000
     , MONTH(craftarr);
";

?>
<table>
  <tr>
    <td>GT</td>
    <td>Jan</td>
    <td>Feb</td>
    <td>Mar</td>
    <td>Apr</td>
    <td>May</td>
    <td>Jun</td> <!--This bit could have been automated too -->
    <td>Jul</td>
    <td>Aug</td>
    <td>Sep</td>
    <td>Oct</td>
    <td>Nov</td>
    <td>Dec</td>
    <td>Total</td>
 </tr>
<?
$result = mysqli_query($conn,$query);
while($row = mysqli_fetch_assoc($result)){

$output = '';
$total = 0;
for($i=1;$i<=12;$i++){

if($row['month'] == $i){ $income = $row['income'] ;} else { $income = 0; }
$total += $income;
$output .= "<td>$income</td>";
}

echo "<tr><td>".$row['GT']."</td>".$output."<td>$total</td></tr>";

}
?>
</tr>
</table>

The output:

GT    Jan    Feb      Mar Apr May Jun Jul Aug Sep Oct Nov Dec  Total
8000  0      246.70   0   0   0   0   0   0   0   0   0   0    246.7
13000 595.07 0        0   0   0   0   0   0   0   0   0   0    595.07
24000 0      480.64   0   0   0   0   0   0   0   0   0   0    480.64
26000 0      557.34   0   0   0   0   0   0   0   0   0   0    557.34
30000 0      637.38   0   0   0   0   0   0   0   0   0   0    637.38
33000 0      956.08   0   0   0   0   0   0   0   0   0   0    956.08
42000 0      1196.25  0   0   0   0   0   0   0   0   0   0    1196.25
52000 0      952.06   0   0   0   0   0   0   0   0   0   0    952.06
71000 0      2082.69  0   0   0   0   0   0   0   0   0   0    2082.69
77000 0      1429.20  0   0   0   0   0   0   0   0   0   0    1429.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM