Group Concat in mysql statement - mysql

I've got a table called delitems with some colums.
Within my SELECT statement I want to use a GROUP_CONCAT:
+-------------------------------+-------+--------+--------+-----+
| COLOR | tOTAL | Ptotal | Amount | qty |
+-------------------------------+-------+--------+--------+-----+
| BLUE - W = 55,BLUE - W/O = 93 | 148 | 375 | 55500 | 2 |
+-------------------------------+-------+--------+--------+-----+
mysql>select GROUP_CONCAT(color,' = ',qty) as COLOR, SUM(qTY) AS tOTAL, suM(p_cost) as Ptotal, SUM(qty)*SUM(p_cost) as Amount,count(*) qty from delitems where status='3' Group By cont_no;
Everything works fine except the Amount column. The total amount is wrong! Here the correct value:
+-----------------+-------+--------+--------+-----+
| COLOR | tOTAL | Ptotal | Amount | qty |
+-----------------+-------+--------+--------+-----+
| BLUE - W = 55 | 55 | 125 | 6875 | 1 |
| BLUE - W/O = 93 | 93 | 250 | 23250 | 1 |
+-----------------+-------+--------+--------+-----+
mysql>select GROUP_CONCAT(color,' = ',qty) as COLOR, SUM(qTY) AS tOTAL, suM(p_cost) as Ptotal, SUM(qty)*SUM(p_cost) as Amount,count(*) qty from delitems where status='3' Group By color;
I only want to display it in one line with the correct total amount
Please help.

Should be you need sum(a*b) not sum(a)*sum(b)
select
GROUP_CONCAT(color,' = ',qty) as COLOR
, SUM(qTY) AS tOTAL
, suM(p_cost) as Ptotal
, SUM(qty*(p_cost) as Amount, count(*) qty
from delitems
where status='3' Group By cont_no;

Related

MySQL group by percent with where clause

i have a table Products
with following fields and values:
ID | Productname | Productprice | Supplier | Available |
+----+-------------+--------------+----------+-----------+
| 1 | Tshirt | 20 | CompanyA | Yes |
| 2 | Pants | 45 | CompanyA | Yes |
| 3 | Shoes | 95 | CompanyB | Yes |
| 4 | Socks | 12 | CompanyA | No |
| 5 | Trainer | 50 | CompanyA | Yes |
How to query how many products belong to CompanyA with status Available=Yes in percentage?
To get the percentage of available products appearing in CompanyA from the overall products, you may use a subquery to calculate that.
SELECT COUNT(*) * 100 / (SELECT COUNT(*) FROM `products`) as `percentage`
FROM `products` WHERE `supplier` = 'CompanyA' and `available` = 'Yes'
Based on your data sample, the above query should return
percentage
+-----+-------+
| 60.0000 |
Considering that by "percent" you mean the number of rows with Available among all rows of that company:
select Supplier, TotalAvailable / Total from(
select
Supplier,
sum( if(Available = 'Yes',1,0) ) as TotalAvailable,
count(*) as Total
from
Products
where
Supplier = 'CompanyA'
group by
Supplier
) a
Or you can use
select
Supplier,
sum( if(Available = 'Yes',1,0) ) / count(*) as Percent
from
Products
where
Supplier = 'CompanyA'
group by
Supplier
Mind that you must handle the "Percent" as it fits for your intentions: multiply by 100, cut the decimals for representation etc.

mysql get total values and total number from where clause

I'm trying to write a mysql query which will return the total number of values from a column and also the total number of values based on a where clause from the same column.
I have a table like this:
+------------------------+-------+
| color | code |
+------------------------+-------+
| red | 200 |
| red | 202 |
| blue | 105 |
| yellow | 136 |
| green | 561 |
| red | 198 |
| blue | 414 |
| green | 11 |
| yellow | 600 |
| green | 155 |
| red | 865 |
| blue | 601 |
| green | 311 |
+------------------------+-------+
If I run this query:
select
color,
count(*) as count
from colors
where code > 0 &&
code <= 500
group by color
order by count(*) desc;
I get this result which is great because it's almost what I want:
+------------------------+-------+
| color | count |
+------------------------+-------+
| red | 3 |
| green | 3 |
| blue | 2 |
| yellow | 1 |
+------------------------+-------+
What I also need returned is the total number of values in the column, so the result table would look like this.
+------------------------+--------------+-------+
| color | total | count |
+------------------------+--------------+-------+
| red | 4 | 3 |
| green | 4 | 3 |
| blue | 3 | 2 |
| yellow | 2 | 1 |
+------------------------+--------------+-------+
So the total is the number of each value in the color column and count is the total amount which matches the where clause.
Thanks :)
Here is the link to SQLFiddle.
http://sqlfiddle.com/#!9/777f93/2
You need to use conditional aggregation to handle the counts and let the engine handle the total.
SELECT color
, count(*) as Total
, sum(case when code > 0 and code <= 500 then 1 else 0 end) as cnt
FROM colors
GROUP BY color
ORDER BY cnt desc;
You can use conditional aggregation:
select color,
count(*) as Total,
sum(code > 0 and code <= 500) as count_0_to_500
from colors
group by color
order by count_0_to_500 desc
It uses the fact that true evaluates to 1 and false evaluates to 0 in MySQL.
It's basically what xQbert answered just without a case expression.
You can JOIN your query with another query, e.g.:
select color, count(*) as count , a.total
from colors JOIN (
SELECT color, count(*) as `total` FROM colors GROUP BY color
) a ON colors.code = a.color
where code > 0 && code <= 500
group by color
order by count(*) desc;
You case use a case when statement to count only those items that meet your criteria. Like this:
Select
color
, count(*) as total
, SUM(CASE WHEN code > 0 && code <= 500 THEN 1 ELSE 0 END ) as Count
group by color order by count(*) desc;
You can do it using join query and table alias
select t1.color,t1.total,t2.count
FROM
(select color, count(*) as total from colors group by color) t1,
(select color, count(*) as `count` from colors where `code` > 0 && `code` <= 500 group by color) t2
WHERE
t1.color=t2.color order by `count` desc;
Here is the link to SQLFiddle.
http://sqlfiddle.com/#!9/777f93/2

Mysql sum with group_concat and join tables

I've trying to solve this problem for about weeks now, but still have no answers
i want to show the total quantity of the inventory_table that has the same product barcode and show also its item description.
I have three tables
product_table
ID| barcode | brand | unit | price
1 | 1111111 | Neozep | Tablet | 5.50
2 | 2222222 | Biogesic | Syrup | 7.50
inventory_table
ID| batch | Total| barcode
1 | 5555555 | 100 | 1111111
2 | 6666666 | 500 | 1111111
productcontains_table
ID| Name | Amount | Type | barcode
1 | Paracetamol | 250 | mg | 1111111
2 | Amoxicilin | 20 | ml | 1111111
And the output should be like this
Barcode | Item Description | Price | Total Qty | Amount
1111111 | Paracetamol 250 mg | Amoxicilin 20 ml | P5.50 | 600 | P3300
My current Sql statement but this is obviously wrong hope you can help me guys
thanks in advance
SELECT
GROUP_CONCAT(DISTINCT productcontains_table.name ,' ',
productcontains_table.Amount,' ',
productcontains_table.Type
ORDER BY productcontains_table.IDno SEPARATOR ' | ' ) AS ItemDescription,
product_table.product_price AS Price,
SUM(inventory_table.inventory_total) AS TotalQuantity
product_table.price AS Price,
SUM(inventory_table.total) AS TotalQuantity,
product_table.price * SUM(inventory_table.total) AS TotalAmount
FROM inventory_table
JOIN product_table
ON product_table.barcode = inventory_table.barcode
JOIN productcontains_table
ON productcontains_table.barcode = product_table.barcode
GROUP BY inventory_table.barcode
Fixed a couple of typos:
SELECT inventory_table.barcode,
GROUP_CONCAT(DISTINCT productcontains_table.name,' ', productcontains_table.Amount,' ', productcontains_table.Type SEPARATOR ' | ') AS ItemDescription,
product_table.price AS Price,
SUM(inventory_table.total)/ b.cnt AS TotalQuantity,
product_table.price * SUM(inventory_table.total) / b.cnt AS Amount
FROM inventory_table
JOIN product_table ON product_table.barcode = inventory_table.barcode
JOIN productcontains_table ON productcontains_table.barcode = product_table.barcode
JOIN
( SELECT barcode,
count(productcontains_table.name) AS cnt
FROM productcontains_table )b ON b.barcode=product_table.barcode
GROUP BY inventory_table.barcode,
product_table.price,
inventory_table.barcode
http://sqlfiddle.com/#!9/2f372/37

Mysql sql query to format a report

This is my table product_details:
Product_Code | Size | Quantity
-------------+------+-----------
CS01 | 10 | 15
CS01 | 11 | 25
CS01 | 12 | 35
PR01 | 40 | 50
PR01 | 41 | 60
I want a the following format for a report to get the total quantity group by product code (all sizes of product code):
Product_Code | Size | Quantity
-------------+------------+----------------
CS01 | 10 11 12 | 75
PR01 | 40 41 | 110
I tried the following query but it does not give the result I want.
SELECT product_no, size, SUM(quantity)
FROM product_details
GROUP BY product_no;
Please help me to find the query to format the report.
You can use group concat
SELECT
product_no,
group_concat(size SEPARATOR ' '),
sum(quantity)
FROM product_details group by product_no;

Mind numbing SQL madness

This query runs on an invoices table to help me decide who I need to pay
Here's the base table:
The users table
+---------+--------+
| user_id | name |
+---------+--------+
| 1 | Peter |
| 2 | Lois |
| 3 | Stewie |
+---------+--------+
The invoices table:
+------------+---------+----------+--------+---------------+---------+
| invoice_id | user_id | currency | amount | description | is_paid |
+------------+---------+----------+--------+---------------+---------+
| 1 | 1 | usd | 140 | Cow hoof | 0 |
| 2 | 1 | usd | 45 | Cow tail | 0 |
| 3 | 1 | gbp | 1 | Cow nostril | 0 |
| 4 | 2 | gbp | 1500 | Cow nose hair | 0 |
| 5 | 2 | cad | 1 | eyelash | 1 |
+------------+---------+----------+--------+---------------+---------+
I want a resulting table that looks like this:
+---------+-------+----------+-------------+
| user_id | name | currency | SUM(amount) |
+---------+-------+----------+-------------+
| 1 | Peter | usd | 185 |
| 2 | Lois | gbp | 1500 |
+---------+-------+----------+-------------+
The conditions are:
Only consider invoices that have not been paid, so where is_paid = 0
Group them by user_id, by currency
If the SUM(amount) < $100 for the user_id, currency pair then don't bother showing the result, since we don't pay invoices that are less than $100 (or equivalent, based on a fixed exchange rate).
Here's what I've got so far (not working -- which I guess is because I'm filtering by a GROUP'ed parameter):
SELECT
users.user_id, users.name,
invoices.currency, SUM(invoices.amount)
FROM
mydb.users,
mydb.invoices
WHERE
users.user_id = invoices.user_id AND
invoices.is_paid != true AND
SUM(invoices.amount) >=
CASE
WHEN invoices.currency = 'usd' THEN 100
WHEN invoices.currency = 'gbp' THEN 155
WHEN invoices.currency = 'cad' THEN 117
END
GROUP BY
invoices.currency, users.user_id
ORDER BY
users.name, invoices.currency;
Help?
You can't use SUM in a WHERE. Use HAVING instead.
Use HAVING clause instead of SUM in WHERE condition
Try this:
SELECT u.user_id, u.name, i.currency, SUM(i.amount) invoiceAmount
FROM mydb.users u
INNER JOIN mydb.invoices i ON u.user_id = i.user_id
WHERE i.is_paid = 0
GROUP BY u.user_id, i.currency
HAVING SUM(i.amount) >= (CASE i.currency WHEN 'usd' THEN 100 WHEN 'gbp' THEN 155 WHEN 'cad' THEN 117 END)
ORDER BY u.name, i.currency;
Try something like this:
SELECT
user_id, name, currency, sum(amount) due
FROM
invoice i
JOIN users u ON i.user_id=u.user_id
WHERE
is_paid = 0 AND
GROUP BY user_id, currency
having due >= 100
do you store exchange rates? Multiply rates with amount to get actual amount with respect to base currency.
sum(amount*ex_rate) due