0

I have four tables, all of which contain columns called:
'location'
'sortiment'
'amount_in' (numerical)
'amount_out' (numerical)

All of them represent different instances in wood processing, such as production, storage, loading on railway cars etc, just FYI. Using different SUM(in-out) queries, I can see the amount of different wood sortiments in each location. But I have to add new queries manually everytime a new location is added, such as a new logging area. Basically the tables are all similar to each other, so that I can use UNION ALL to sum up everything everywhere!

Now what I want to do, is creating a table with a single query, that will basically look like this:

|             | location A | location B | location C |
|-------------|------------|------------|------------|
| sortiment A |  sum(AA)   |  sum(AB)   |  sum(AC)   |
| sortiment B |  sum(BA)   |  sum(BB)   |  sum(BC)   |
| sortiment C |  sum(CA)   |  sum(CB)   |  sum(CC)   |

All of the tables contain all sortiments, but every table has different locations.

Here's what I tried first:

SELECT location, sortiment, SUM(amount_in-amount_out)
FROM (
SELECT location, sortiment, amount_in, amount_out FROM Eproduction 
UNION ALL
SELECT location, sortiment, amount_in, amount_out FROM Estorage 
UNION ALL
SELECT location, sortiment, amount_in, amount_out FROM Elogdepot
UNION ALL
SELECT location, sortiment, amount_in, amount_out FROM Erailway
) x
GROUP by location";

and then the loop

echo "<tr><td>".$row['sortiment']. "</td><td>" .(float)$row['SUM(amount_in-amount_out)']."</td></tr>";

obviously resulting in this

| sortiment A | sum(AA) |
| sortiment B | sum(BA) |
| sortiment C | sum(CA) |
| sortiment A | sum(AB) |
| sortiment B | sum(BB) |
| sortiment C | sum(CB) |etc

which is not what I wanted to achieve.

Then I tried aliases:

SELECT location, sortiment, 
SUM(in_pr-out_pr), 
SUM(in_sto-out_sto), 
SUM(in_log-out_log), 
SUM(in_rail-out_rail)
FROM (
SELECT location, sortiment, amount_in AS in_pr, amount_aout AS out_pr FROM Eproduction 
UNION ALL
SELECT location, sortiment, amount_in AS in_sto, amount_out AS out_sto FROM Estorage 
UNION ALL
SELECT location, sortiment, amount_in AS in_log, amount_out AS out_log FROM Elogdepot
UNION ALL
SELECT location, sortiment, amount_in AS in_rail, amount_out AS out_rail FROM Erailway
) x
GROUP by location, sortiment";

and then the loop

echo "<tr><td>".$row['location']. "</td><td>".$row['sortiment']. "</td><td>" .(float)$row['SUM(in_pr-out_pr)']."</td><td>" .(float)$row['SUM(in_sto-out_sto)']."</td><td>" .(float)$row['SUM(in_log-out_log)']."</td><td>" .(float)$row['SUM(in_rail-out_rail)']."</td></tr>";

Which in my understanding should create the table I want, BUT it returns 'unknown field 'in_sto'' error.

Any help appreciated, thanks in advance!

wogsland
  • 9,106
  • 19
  • 57
  • 93
  • you're doing a pivot query, and mysql doesn't support them. you are using the usual workaround, and as you've seen, it's not scalable. Your choices are to a) bite the bullet and mod queries as necessary when new columns are needed b) fetch the data conventionally and pivot in client-side code c) switch to a different DB that DOES support pivots. – Marc B Jan 21 '16 at 14:46
  • 2
    `in_pr-out_pr` that translates to `in_pr` **MINUS** `out_pr` same for the others containing hyphens. MySQL thinks you want to do math on the column "names" instead of data. Check for errors. – Funk Forty Niner Jan 21 '16 at 14:47
  • d) build a sproc (although I'd stick with (b) ) – Strawberry Jan 21 '16 at 15:34

0 Answers0