I have the following tables:
Stocks
id | name | amount |
---|---|---|
1 | Pen | 35 |
2 | Cd | 21 |
3 | Bag | 15 |
StockUnits
id | name | include | stockid |
---|---|---|---|
1 | onepen | 1 | 1 |
2 | dozen | 6 | 1 |
3 | 24 | 1 | |
4 | onecd | 1 | 2 |
5 | 5 | 2 | |
6 | onebag | 1 | 3 |
So how do I get a result like the following with SELECT query?
stock | unit | qty |
---|---|---|
Pen | onepen | 5 |
Pen | dozen | 1 |
Pen | 1 | |
Cd | onecd | 1 |
Cd | 4 | |
Bag | onebag | 15 |
As we see, each stock has some units.
Now I want to know how many units do i have according to the amount field, For example:
We have 35 pens which is equal to 1 pocket and 1 dozen and 5 onepen because:
For pocket we have 1 pocket because (each pocket includes 24 pen)
35/24=1
35$=11
For dozen we have 1 dozen because (each dozen includes 6 pen)
11/6=1
11%6=5
For onepen we have 5 onepen because
5 onepen because we don't have any smaller unit
Now we have:
1 pocket
1 dozen
5 onepen
Same calculation for Cd and Bag...
I know to get the desired result a temporary variable should be used to store the result of the MOD and use the variable for the next row but how?
CodePudding user response:
How to store a result of a row in a variable and use it in the next row in MySQL SELECT query?
A pattern for MySQL version 5.x:
SELECT .. ,
{an expression which uses @variable with the value from previous row} AS calculated_column,
.. ,
@variable := {an expression for current row which will be used for next row processing} AS dummy_column,
..
FROM {source single table or subquery}
CROSS JOIN ( SELECT @variable := {initial variable value} ) AS init_variable
ORDER BY {ordering expression which provides rows uniqueness}
On MySQL 8 use window function(s).
CodePudding user response:
First of all, your Stocks
and StockUnits
make no sense, or they are at least bad designed.
You show that you store the id
of each stock-row in multiple unit-rows, but it really should be the other way around.
How Stocks
table should be:
id | name | qty | unit_id |
---|---|---|---|
1 | Pen | 5 | 1 |
2 | Pen | 1 | 2 |
3 | Pen | 1 | 3 |
... |
How StockUnits
table should be:
id | name | include |
---|---|---|
1 | onepen | 1 |
2 | dozen | 6 |
3 | 24 | |
... |
Example
Once you fix the design mistake, all you would need to do is join
to get unit's name, for example in Laravel do something like:
$stockTable = Stock::with('unit')->all();
echo 'stock | unit | qty';
foreach ($stockTable as $item) {
echo $item->name . ' | ' . $item->unit->name . ' | ' . $item->qty;
}
To get output:
name | unit | qty |
---|---|---|
Pen | onepen | 5 |
Pen | dozen | 1 |
Pen | packet | 1 |
... |