SQL Table Solution With Calculating Different Columns in Same Table - mysql

I have a sql table like :
id buy_product buy_product_total sell_product sell_product_total
1 apple 5
2 banana 8
3 cake 20
4 apple 1
5 cake 2
6 apple 2
My problem is, I want to show product name and how many product left. Like :
product_name left
apple 6
cake 18
How can I show like that solution with sql query ?
I create table as answerers as :
Buy Table
id product_name total
1 apple 5
2 banana 8
3 cake 20
4 apple 2
Sell Table
id product_name total
1 apple 1
2 cake 2
I want to table like this
product_name left
apple 6
banana 8
cake 18

Is not a good table, could be better that buy and sell to be the same collumn buy with positive values and sell with negative.
But answer your question, suppose that your table name is myTable,
obs: you can execute every select separeted to understand better
select buy_product as product_name, (buy_total - sell_total) as left
from (
(select buy_product, sum(buy_product_total) as buy_total
from myTable where buy_product_total is not null group by buy_product) as buy_list
inner join
(select sell_product, sum(sell_product_total) as sell_total
from myTable where sell_product_total is not null group by sell_product) as sell_list
on buy_list.buy_product = sell_list.sell_product
)

As others have noted, your table structure is less than optimal.
However, given what you have, this will give you the results you're after.
select product, sum(total) from
(
select buy_product as product, buy_product_total as total
from yourtable
where buy_product is not null
union
select sell_product, -sell_product_total
from yourtable
where sell_product is not null
) v
group by product
Or, with your two tables
select product_name, sum(total) from
(
select product_name, total
from buy_table
union
select product_name, -total
from sell_table
) v
group by product_name

You should consider a different database design that is more appropriate (You may want to read up on normalization), but query follows:
SELECT t1.buy_product_total - t2.sell_product_total
FROM ProductTable t1, ProductTable t2
WHERE t1.buy_product = t2.sell_product
i.e. You're joining the table to itself using a 'self join'...

Related

mySQL: linking multiple rows from another table to a single cell using their id's [duplicate]

So basically as an example, here's a table of foods and the date they were consumed on by different people
consumption
user_id
food
date
1
apple
12-DEC-09
1
banana
12-DEC-09
1
strawberry
13-DEC-09
2
apple
14-DEC-09
2
apple
15-DEC-09
2
orange
15-DEC-09
I want to select all foods that each user_id ate on each unique date, so the output looks something like:
user_id
food
date
1
apple, banana
12-DEC-09
1
strawberry
13-DEC-09
2
apple
14-DEC-09
2
apple, orange
15-DEC-09
I've tried something like this:
SELECT food
FROM consumption
WHERE food IN (
SELECT food
FROM consumption
GROUP BY food, `date`
)
GROUP BY user_id;
But I'm stumped. Any help would be appreciated!
The group in your case is rows group where both user_id and date is the same. Hence you must group by these two columns.
You need all food names concatenated into single value within a group. Hence you must use according aggregate function.
SELECT user_id, GROUP_CONCAT(food) food_list, `date`
FROM consumption
GROUP BY user_id, `date`;

Find the number of orders related to each order size in MySQL

Need some help with a MySQL query to be used in a larger database. Simplified here, I need to find the number of orders related to each order size.
I've been trying to get the query to work with a lot of combinations like: COUNT(DISTINCT item) or GROUP_CONCAT(DISTINCT order_id), GROUP BYs, ORDER BYs, HAVING COUNT(DISTINCT item_id), etc. but it's not turning out like I really need it to. Any help toward getting me going in the right direction would be greatly appreciated.
In this example table named items, the person with an order_id of 1 ordered three items, the person with an order_id of 4 ordered only one item, the person with an order_id of 5 ordered two items, etc. At the moment, they can only order up to three items max, but in the future, more items could be added so the query needs to be written in a way that can scale to 4 items, 5 items, etc.
Table name is: items
item_id order_id item
-------------------------------
1 1 apple
2 1 orange
3 1 grape
4 2 grape
5 3 apple
6 3 orange
7 4 apple
8 5 orange
9 5 apple
10 6 apple
11 6 orange
12 6 grape
13 7 orange
14 8 grape
In this example, the query result would be:
Number_of_Orders Total_Order_Size
----------------------------------------
4 1
2 2
2 3
You have to group by twice.
select item_count,count(*)
from (select order_id,count(*) as item_count
from tbl
group by order_id
) t
group by item_count
You can use two levels of aggregation:
select num_items, count(*) as num_orders
from (select order_id, count(*) as num_items
from t
group by order_id
) o
group by num_items
order by num_items;

Use COALESCE within SUM in MySQL SELECT statement

I have the following tables:
Table users
id name base_discount
1 jack 10
2 michael 20
3 richard 30
Table item
id name category_id price
1 hammer 1 10
2 knife 2 15
3 spoon 2 12
4 plate 3 20
5 tree 4 400
Table category
id name
1 tools
2 kitchen
3 dishes
4 garden
Table discount_category
id user_id category_id discount
1 1 1 20
2 1 3 25
3 3 3 10
4 1 2 15
Table discount_item
id user_id item_id discount
1 2 1 50
2 1 2 50
Now what I want to achieve. I want to attach the discount per item that a user has to the correct item. If that is not available (NULL) I want to attach the discount per category that a user has. And if that is not available (NULL), I want to attach the base discount that a user has. With the discount I then calculate the new price of the item. However, when I try using COALESCE() within SUM() I get a syntax error. What am I doing wrong?
Below is my current query:
SELECT item.id, item.name, category.id,
category.name AS category_name, item.price, SUM((100 -
COALESCE(
(
SELECT discount_item.discount
FROM discount_item
INNER JOIN users ON discount_item.user_id = users.id
WHERE users.id = '1' AND discount_item.item_id = item.id
),
(
SELECT discount_category.discount
FROM discount_category
INNER JOIN users ON discount_category.user_id = users.id
WHERE users.id = '1' AND discount_category.category_id = item.category_id
),
(
SELECT users.base_discount
FROM users
WHERE users.id = '1'
)
)) / 100 * item.price) AS new_price,
FROM item
INNER JOIN category ON item.category_id = category.id;
Please also see the below link for an SQL Fiddle (couldn't do it on sqlfiddle.com as it wouldn't load). In the example I have appended a suffix to each table name.
http://rextester.com/LCCKSD59098
You have an extra comma after new_price and before FROM ITEM, hence the error.
Rextester Demo
Do not select other columns in select if you are not using them in group by, as in other relational RDBMS, you will get error.
Also use alias for table names for better readibily and to avoid confusion.

Count Category products with mysql

I have to count products inside each category like I have a category A that have two childs B and C.
In B category have 10 products and C category have 5 Products.
I want to write a query that count product like A = 15 B = 10 C = 5.
I have wrote a query that count only for child categories.
My query is given below
SELECT
c.`id`,
c.`parent_id`,
c.`name`,
c.`slug`,
c.`route_id`,
c.`description`,
c.`excerpt`,
c.`sequence`,
c.`image`,
c.`seo_title`,
c.`meta`,
c.`enabled`,
(SELECT
COUNT(`product_id`)
FROM
HM_category_products
WHERE
HM_category_products.category_id IN (SELECT
HM_categories.`id`
FROM
HM_categories
WHERE
(id = c.`id` OR id = c.`parent_id`))) AS count
FROM
`HM_categories` AS c
EDITED :- Below is my tables structure. This is just an example.
Category Table
id parent_id name slug enabled
1 0 Mobiles & Tablets mobiles-tablets 1
2 1 Mobile Phones mobile-phones 1
3 1 Tablets tablets 1
4 1 Mobile Accessories mobile-accessories 1
5 0 Electronics & Computers electronics-computers 1
6 5 Cameras & Accessories cameras-accessories 1
7 5 TV - Video - Audio tv-video-audio 1
Category Product Table
product_id category_id
1 2
2 2
3 2
4 2
5 3
6 2
7 3
8 3
9 3
10 2
11 3
12 2
13 2
14 2
15 2
You hav to use the "Group by" with something like:
SELECT
category_id, COUNT(*)
FROM
HM_category_products
GROUP BY category_id
This would get your table HM_category_products Grouped by category_id so will know how mane rows of each category its in the table, whats mean you will know the number of product of each category. Then you can join this resulting table with category one to get the category info. (Sorry for my english)
The GROUP BY statement is used in conjunction with the aggregate
functions to group the result-set by one or more columns. SQL GROUP BY Statement
for more info abaut "Group by" read
12.16.2 GROUP BY Modifiers and
12.16.1 GROUP BY (Aggregate) Functions
EDIT: I see now what you whant. I already give you the direction but here its a step furder: DISCLAIMER: THIS QUERY ITS JUST EXAMPLE, IT DOSNT WORK
CREATE VIEW view_2 AS
SELECT
category_id, COUNT(*) AS product_sum
FROM
HM_category_products
GROUP BY category_id
CREATE VIEW view_1 AS
SELECT
*
FROM
HM_categories
LEFT JOIN
view_2 AS a ON HM_categories.id = a.category_id;
SELECT
id,
name,
(SELECT
SUM(product_sum)
FROM
view_1
WHERE
parent_id = final.id) as product_count
FROM
HM_categories AS final;
that way you will get the product of a parent category, your only missing a CASE on the last select "product_count" to the child categorys, but that sum its easy because you already hav it on the view_1 (again sorry for my english)

Group by various column (with various joins) but sum distinct other column

I have to do some reporting, involving various tables, and having couple of SUMs, COUNTs, etc and everything is OK. But the last thing I have to resolve is SUM by another which is not in the grouped columns.
I'll give you an example (stripped down from what I have) so you can understand the tongue-twister in the previous paragraph.
Suppose I have a query with a couple of joins that get me this result, or a temporary table, or whatever:
(this is a trimmed down version, in the original I have much more columns and groupbys)
APP_ID CAT_ID CAT_DESCRIP APP_START APP_END DETAIL_ID DET_QTY DETAIL_PRICE
1 1 Categ One 900 960 1 10 150.00
1 1 Categ One 900 960 2 8 20.00
1 1 Categ One 900 960 3 12 30.00
1 1 Categ One 900 960 4 5 100.00
2 2 Categ Two 600 720 5 12 150.00
2 2 Categ Two 600 720 6 10 50.00
3 2 Categ Two 1200 1260 7 5 20.00
I need to get something like this: (the bolded column is the important)
SELECT
CAT_ID,
CAT_DESCRIP,
SUM(DET_QTY) as TotalQTY,
SUM(DETAIL_PRICE) as TotalPrice,
COUNT(DISTINCT APP_ID) as CountOfApps,
(GET THE SUM OF (APP_END - APP_START) ONLY ONE TIME BY APP_ID INTO THIS CATEG) as TimeInMinutesByCategory
FROM
MyTable
GROUP BY
CAT_ID
And the result has to give me this:
CAT_ID CAT_DESCRIP TotalQTY TotalPrice CountOfApps TimeInMinutesByCategory
1 Categ One 35 300.00 1 60
2 Categ Two 27 220.00 2 180
Thanks for your help!
I think this will do the job... or if not, a little tweaking on the sytnax for max(app_start) - max(app_end) should do the job
The idea is, summarize the data in a subquery by app_id and cat_id. Select the max value of start and end, grouped by app_id and cat_id. Since there will only be one value per each distinct pair of app_id and cat_id, we're essentially just deduping.
Then, join the subquery to the main query and summarize by category id.
SELECT
a.CAT_ID,
a.CAT_DESCRIP,
SUM(a.DET_QTY) as TotalQTY,
SUM(a.DETAIL_PRICE) as TotalPrice,
COUNT(DISTINCT a.APP_ID) as CountOfApps,
SUM(b.TimeInMinutesByCategory) AS TimeInMinutesByCategory
FROM
MyTable AS a
INNER JOIN (
SELECT APP_ID, CAT_ID, max(app_start) - max(app_end) AS TimeInMinutesByCategory
FROM MyTable
GROUP BY APP_ID, CAT_ID) AS b
ON a.cat_id = b.cat_id
AND a.app_id = b.app_id
GROUP BY
a.CAT_ID