How to merge two rows and sum the columns - sql

product
quantity
price
milk
3
10
bread
7
3
bread
5
2
And my output table should be
product
total_price
milk
30
bread
31
I can't seem to get my code to work. Here is my code
SELECT product, (SELECT (quantity*unit_price)
FROM shopping_history AS sh ) AS total_price
FROM shopping_history
GROUP BY product

You are looking for the aggregate function SUM (which doesn't require a sub-query) e.g.
SELECT product, SUM(quantity*unit_price) AS Total_Price
FROM shopping_history
GROUP BY product

Related

How to group by condition and average only if column value is not null in bigquery sql

Hi I have a table that shows the category of product and another table with daily price of the product. I would like to get the average price of the category where average not count null values. How do I achieve this? Example of table product
product
category
apple
fruit
pear
fruit
grape
fruit
celery
vegetables
cabbage
vegetables
chicken
meat
turkey
meat
beef
meat
another table with daily price and productid as columns and the price in the rows
date
apple
pear
grape
celery
cabbage
chicken
turkey
beef
2022-01-01
2
4
1
2
3
4
3
2022-01-02
2
2
2
4
3
2022-01-03
2
2
2
3
into
date
fruit
vegetables
meat
2022-01-01
3
1.5
3.3
2022-01-02
2
2
3.5
2022-01-02
2
2
3
Where average is only to columns where it is not null, it would be better not to do it manually.
Consider below query using UNPIVOT AND PIVOT:
SELECT * FROM (
SELECT date, category, price
FROM prices UNPIVOT (price FOR productid IN (apple, pear, grape, celery, cabbage, chicken, turkey, beef)) p
JOIN category c ON c.product = p.productid
) PIVOT (AVG(price) FOR category IN ('fruit', 'vegetables', 'meat'))
ORDER BY date;
Consider also below approach
create temp function keys(input string) returns array<string> language js as """
return Object.keys(JSON.parse(input));
""";
create temp function values(input string) returns array<string> language js as """
return Object.values(JSON.parse(input));
""";
select *
from (
select date, category, round(avg(safe_cast(price as float64)), 2) avg_price
from prices t, unnest([struct(to_json_string(t) as json)]),
unnest(keys(json)) product with offset
join unnest(values(json)) price with offset using(offset)
left join products using(product)
where product != 'date'
group by date, category
)
pivot (any_value(avg_price) for category IN ('fruit', 'vegetables', 'meat'))
if applied to sample data in your question - output is
Potential benefit of using above is to eliminate need in enlisting all column names from products table, which are 8 in your example but in reality most likely much more! Obviously, another way to address this is to build dynamic query and run it using execute immediate which you can find quite a number of examples here on SO.
But, assuming that number of categories is significantly lower (just few as in your example) to compare with number of products - I would use this approach as execute immediate has its own drawbacks ...

SQL how to return column values with same name only once

I have a table containing 3 columns consisting of a product (varchar), quantity(integer), price(integer). I want to get the total price of the products and return the product and the total price and ordered by descending alphabetical order. But if the product is repeated I only want to return the product once with its total price.
Heres the table:
product
quantity
price
Pencil
2
4
Notebook
3
5
Notebook
5
5
In this case desired output would be :
product
totalprice
Notebook
40
Pencil
8
My current output is this:
product
totalprice
Notebook
15
Notebook
25
Pencil
8
My query is the following:
SELECT product, quantity * price AS totalprice
FROM schoolproducts
ORDER BY product DESC
This is a case for aggregation:
SELECT product, sum(quantity * price) AS totalprice
FROM schoolproducts
GROUP BY product
ORDER BY product DESC

Calculating percentages per product using aggregate functions and group by

I have a table with 5 rows representing two different products. The columns include the product, sales, discount. I'm trying to calculate the percentage of sales per product that included a discount. The table looks like this:
product
sales
discount
1
10
0
1
10
5
2
20
10
2
20
0
2
20
10
My results should look like the below (which I know because I've calculated this in Excel):
product
perc_discount
1
50.00
2
66.67
For each of the two products we are calculating the count of sales with discount divided by the total count of sales, so for product 1 it would be (1/2)*100 = 50.
My SQL code looks like the below:
SELECT
product,
(SELECT COUNT(*) FROM sales WHERE discount >0)/COUNT(*)*100 AS perc_discount
FROM sales
GROUP BY product
However, the result I'm getting is:
product
perc_discount
1
150.0
2
100.0
It seems to be calculating the total count of discounted sales in the table and diving it by the count of each product and I can't seem to figure out how to change it. Any ideas on how I can improve this?
Thanks.
How about conditional sum?
SQL> select product,
2 round(sum(case when discount > 0 then 1 else 0 end) / count(*) * 100, 2) perc_discount
3 from sales
4 group by product;
PRODUCT PERC_DISCOUNT
---------- -------------
1 50
2 66,67
SQL>
So: add 1 for every discount row per product. Divide that sum with total number of rows per product (that's count). Round the result to 2 decimals (so that it looks prettier).
You can use conditional aggregation. For example:
select
product,
100.0 * count(case when discount <> 0 then 'x' end) / count(*) as perc_discount
from sales
group by product

Select the best selling product ID

What if I have table like this and I want to select the best selling product_id.
id
transaction_id
product_id
qty_sold
1
21
2
5
2
22
3
2
3
23
4
2
3
24
2
1
3
25
2
4
I want the best selling product_id with the highest qty_sold
Using SQLS, you can group by the productID, add up the number of sold, and order by the total descending. If we also take the minimum transaction ID per product, if two products come out to have the same total qty, we can take the minimum tran ID to split the tie
SELECT TOP 1 product_id, SUM(qty_sold) as sellcount, MIN(transaction_id) as firsttran
FROM t
GROUP BY product_id
ORDER BY SUM(qty_sold) DESC, MIN(transaction_id)
Once you're happy the sums are right etc, you can remove the , SUM(qty_sold) as sellcount, MIN(transaction_id) from the SELECT if you want/if you only need the prod ID

How to add values of the same item in a column?

I have the following columns in a table:
Product Name
Quantity
Description
I want to add the quantities of the product if the name of the product is same. For example if I have product with the same name twice, I want the total quantities of the products to be added and get a result.
This is the table and I want to add the quantities of the same item:
Name Quantity Description
Pen 3
Pencil 2
Pen 6
Eraser 7
Eraser 6
For exmaple:
I have pen twice and so want to add (3+6) and the display the total as 9, and ...
I have eraser twice (7+6), so the total should be 13.
The solution is GROUP BY clause:
SELECT Name, SUM(Quantity)
FROM Table
GROUP BY Name
GROUP BY is used in an SQL query to group rows together for aggregation purposes.
For example:
If your input table had rows:
ItemName Qty
Pen 4
Pencil 7
Pen 6
SQL Code:
SELECT ItemName, SUM(Qty)
FROM Table
GROUP BY ItemName
Using GROUP BY ItemName in your query would give you the output:
ItemName Qty
Pen 10
Pencil 7
SELECT SUM(column_name) FROM table_name
This is the best example!