Mysql and Triggers usage - mysql

I wonder what's the best practice is when you have a table like this below with orders. I need to calculate the total price of each order. Should I use triggers to calculate the price or should I hardcode the calculation before insert into database?
ORDERS:
id | Article | Price | Quantity | Total price
---------------------------------------------
1 | TV | 5 | 1 | 5
2 | CD | 3 | 2 | 6
3 | Book | 2 | 3 | 6
4 | XBOX | 1 | 1 | 1

Related

Precalculate numbers of records for each possible combination

I have a mySQL database table containing cellphones information like this:
ID Brand Model Price Type Size
==== ===== ===== ===== ====== ====
1 Apple A71 3128 A 40
2 Samsung B7C 3128 B 20
3 Apple ZX5 3128 A 30
4 Huawei Q32 2574 B 40
5 Apple A21 2574 A 25
6 Apple A71 3369 A 30
7 Samsung A71 7413 C 40
Now I want to create another table, that would contain counts for every possible combination of the parameters.
Params Count
============================================== =======
ALL 1000000
Brand(Apple) 20000
Brand(Apple,Samsung) 40000
Brand(Apple),Model(A71) 7100
Brand(Apple),Type(A) 6000
Brand(Apple),Model(A71,B7C),Type(A,B) 7
Model(A71) 12514
Model(A71,B7C) 26584
Model(A71),Type(A) 6521
Model(A71),Type(A,B) 8958
Model(A71),Type(A,B),Size(40) 85
And so on for every possible combination. I was thinking about creating a stored procedure (that i would execute periodically), that would perform queries with every existing condition like that, but I am a little stuck on how exactly should it look like. Or is there a better way how to do this?
Edit: the reason why I want to store information like this is to be able to show number of results in filter in client application, like in the picture.
I would like to create index on the Params column to be able to get the Count number for given hash instantly, improving performance.
I also tried querying and caching the values dynamically, but I want to try this approach as well, so I can compare which one is more effective.
This is how I am calculating the counts now:
SELECT COUNT(*) FROM products;
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple', 'Samsung');
SELECT COUNT(*) FROM products WHERE Brand IN ('Apple') AND Model IN ('A71');
etc.
You can use a ROLLUP for this.
SELECT
model, type, size, COUNT(*)
FROM mytab
GROUP BY 1, 2, 3
WITH ROLLUP
With your sample data, we get the following:
| model | type | size | COUNT(*) |
| ----- | ---- | ---- | -------- |
| A21 | A | 25 | 1 |
| A21 | A | | 1 |
| A21 | | | 1 |
| A71 | A | 30 | 1 |
| A71 | A | 40 | 1 |
| A71 | A | | 2 |
| A71 | C | 40 | 1 |
| A71 | C | | 1 |
| A71 | | | 3 |
| B7C | B | 20 | 1 |
| B7C | B | | 1 |
| B7C | | | 1 |
| Q32 | B | 40 | 1 |
| Q32 | B | | 1 |
| Q32 | | | 1 |
| ZX5 | A | 30 | 1 |
| ZX5 | A | | 1 |
| ZX5 | | | 1 |
| | | | 7 |
The subtotals are present in the rows with null values in different columns, and the total is the last row where all group by columns are null.

MySQL get the row with smallest column value for each product group [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 3 years ago.
I have tables products and product_prices. Like that;
products:
+-------------+----------+
| products_id | title |
+-------------+----------+
| 1 | phone |
| 2 | computer |
| 3 | keyboard |
+-------------+----------+
product_prices:
+-------------------+-----------+-------+-------------+
| product_prices_id | productid | price | minquantity |
+-------------------+-----------+-------+-------------+
| 1 | 1 | 500 | 1 |
| 2 | 1 | 450 | 2 |
| 3 | 2 | 800 | 1 |
| 4 | 2 | 700 | 2 |
| 5 | 3 | 15 | 1 |
| 6 | 3 | 10 | 3 |
| 7 | 3 | 7 | 10 |
+-------------------+-----------+-------+-------------+
So there's multiple prices depending on quantity.
My SQL query is like this:
SELECT
*
FROM
products product
INNER JOIN
product_prices price
ON price.productid = product.products_id
GROUP BY
product.products_id
ORDER BY
price.price;
I'm getting this error:
Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'price.product_prices_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
The result without GROUP BY is:
+-------------+----------+-------------------+-----------+-------+-------------+
| products_id | title | product_prices_id | productid | price | minquantity |
+-------------+----------+-------------------+-----------+-------+-------------+
| 3 | keyboard | 7 | 3 | 7 | 10 |
| 3 | keyboard | 6 | 3 | 10 | 3 |
| 3 | keyboard | 5 | 3 | 15 | 1 |
| 1 | phone | 2 | 1 | 450 | 2 |
| 1 | phone | 1 | 1 | 500 | 1 |
| 2 | computer | 4 | 2 | 700 | 2 |
| 2 | computer | 3 | 2 | 800 | 1 |
+-------------+----------+-------------------+-----------+-------+-------------+
What I want to do is, get the row with the cheapest price, grouped by products_id;
+-------------+----------+-------------------+-----------+-------+-------------+
| products_id | title | product_prices_id | productid | price | minquantity |
+-------------+----------+-------------------+-----------+-------+-------------+
| 3 | keyboard | 7 | 3 | 7 | 10 |
| 1 | phone | 2 | 1 | 450 | 2 |
| 2 | computer | 4 | 2 | 700 | 2 |
+-------------+----------+-------------------+-----------+-------+-------------+
I think I need to use MIN() but I have tried several things, which did not work. The closest I could do was ordering it by price, limiting to 1, but it was returning 1 product only.
Any ideas?
If it helps, here's the dump for example database I used: https://transfer.sh/dTvY4/test.sql
You need first to find out what are the minimum prices for each product. For that you use the MIN-aggregate function. As you are selecting a normal columnn with aggregate function, you need to list the normal column in the GROUP BY-clause.
Once you know the minimum prices for each product, you just select those rows from the join of the two tables:
select
p.products_id,
p.title,
pr.product_prices_id,
pr.productid,
pr.price,
pr.minquantity
from product_prices pr
join products p on p.products_id=pr.productid
join (
select productid, min(price) as minprice
from product_prices
group by productid
) mpr on mpr.productid=pr.productid and mpr.minprice=pr.price
See SQLFiddle.
In your query you try to use GROUP BY-clause without an aggregate function, hence the error. Also, you are missing the MIN-logic.
Instead of linking a file to the question, you better create a SQLFiddle / db-fiddle for it. This way it is far easier to answer the question.

MS Access - display repeating rows once with the highest value

I have 2 tables in MS Access with the following values
Customer
id | name
1 | jon
2 | bob
3 | jack
Order
id | amount | date | customer
5 | 50 | 3/10/2017 | 1
4 | 100 | 3/10/2017 | 1
3 | 45 | 2/28/2017 | 2
2 | 10 | 3/10/2017 | 3
1 | 5 | 3/10/2017 | 2
I want to get an output of
name | orderid | amount
jon | 5 | 50
bob | 3 | 45
jack | 2 | 10
I want to get amount of the latest order id per customer, however I keep getting this
name | orderid | amount
jon | 5 | 50
jon | 4 | 100
bob | 3 | 45
bob | 2 | 10
jack | 1 | 5
I used the query designer and have used the function MAX() to the order id, GROUP BY to all columns (MS Access does not allow to group the rows using a single column), DISTINCT and DISTINCTROW, as well as set the query properties "Unique Records" to Yes but the duplicate records still shows.

Fifo sorting a sql table

I have a table called Transactions which looks like this:
Id | date | type | price | quantity | buysell
1 | 0001 | 1 | 1.00 | 3 | buy
2 | 0002 | 2 | 5.00 | 1 | buy
3 | 0003 | 3 | 0.30 | 2 | buy
4 | 0006 | 1 | 1.50 | 1 | sell
5 | 0007 | 4 | 7.00 | 12 | buy
6 | 0011 | 2 | 6.00 | 1 | sell
7 | 0015 | 3 | 0.50 | 2 | sell
8 | 0016 | 1 | 1.50 | 2 | sell
9 | 0017 | ....
I need to find a way how to match all sell transactions to related buy transactions. This should be done in the fifo principle: In the example above, transaction 4 should match to 1, 6 to 2, 7 to 3 and 8 to 1 (depending on the type). Also the quantity field has to be considered - transaction 1 for example has two fulfilling sell transactions which sum up to the buy quantity of 3.
Is there a way to achieve this with mysql or any other database system?
Edit
The desired resulset could for example be a table of all sell transactions and their related buy transactions:
Id | sellid | buyid
1 | 4 | 1
2 | 6 | 2
3 | 7 | 3
4 | 8 | 1
Based on this table, I can calculate margins or the time it takes to sell something (for example).
you may try the below model
select *,
(select sum(case when buysell='buy' then quantity else -quantity end) from yourTable a
where a.type1=b.type1 and a.date1<=b.date1) bls
from yourTable b order by type1,id

database design for sale system

In a simple sales sample I have 3 primary tables: Order, Product, Orders_Products:
Product table
+----+-----------+
| id | name |
+----+-----------+
| 1 | A |
| 2 | B |
+----+-----------+
order table
+----+---------+------------+------------+---------------------+
| id | user_id | total_cost | order_date | status_id |
+----+---------+------------+------------+---------------------+
| 1 | 5 | 25.00 | 2012-02-03 23:30:24 | 1 |
| 2 | 7 | 30.00 | 2012-02-13 18:06:12 | 1 |
+----+---------+------------+------------+---------------------+
orders_products table
+----+----------+------------+--------+
| id | order_id | product_id | cost |
+----+----------+------------+--------+
| 1 | 1 | 34 | 10.00 |
| 2 | 1 | 25 | 10.00 |
| 3 | 1 | 27 | 2.50 |
| 4 | 1 | 36 | 2.50 |
| 5 | 2 | 75 | 25.00 |
| 6 | 2 | 74 | 5.00 |
+----+----------+------------+--------+
But in my system:
A user adds money into his account then he can spend it
Products are services like Product A: user can post 5 Ads so when user post a Ads that 5 become 4 and so on.
How should I design DB for it??
You currently have no table to store customer data. I would strongly advise creating one using an Auto-Increment ID field, a name field and a field to store the money on their account which can be modified when the add money to it or purchase something.
In the Order table, the user_id field should be a foreign key from the Customer table I just told you how to create.
If you want to better understand what you should be doing, I would recommend looking at the Entity-Relationship Model
I don't entirely understand what your second question is, can you explain it in more detail? Are all the products just a set number of ads that the customer can post?