mysql SUM CASE self join - mysql

i need some help with this query
this is the actual result of my query
price received qty recieved price release qty release
10.30 10 0 0
0 0 10.30 2
0 0 10.30 1
19.20 20 0 0
0 0 19.20 5
0 0 19.20 3
0 0 19.20 1
Using this code in my query
$result = mysql_query("SELECT *,
SUM(CASE WHEN qtyreceived > 0 THEN qtyreceived END) AS qtyrec,
SUM(CASE WHEN qtyrelease > 0 THEN qtyrelease END) AS qtyrel
FROM stockledger
WHERE stockdesc= '$_POST[desc]' GROUP BY pricerelease,pricereceived ");
the results was
price received qtyreceived price release qtyrelease bal
10.30 10 10
19.20 20 20
10.30 3 -3
19.20 9 -9
and i want to view the result this way so i can get the remaining number for 2 prices
price received qtyreceived price release qtyrelease bal
10.30 10 10.30 3 7
19.20 20 19.20 9 11
thanks.....;

From seeing your data, I think it will be based on the prices. Right? try this one.
SELECT a.PriceReceived,
a.qtyreceived,
b.priceRelease,
b.qtyRelease,
(a.bal + b.bal) as bal
FROM stockledger a
INNER JOIN stockledger b
ON a.priceReceived = b.priceRelease
or another alternative is
SELECT a.PriceReceived,
a.qtyreceived,
b.priceRelease,
b.qtyRelease,
(a.qtyreceived - b.qtyRelease) as bal
FROM stockledger a
INNER JOIN stockledger b
ON a.priceReceived = b.priceRelease
SQLFiddle Demo

Related

How to use count in sql based on a IF condition

From this table
groupId
flag
flagValue
1
0
500
2
0
100
1
1
10
2
1
50
3
0
100
1
1
200
3
1
1000
2
1
50
I need this result
groupId
flag1
flag0
valFlag1
valFlag0
totalFlags
1
2
1
210
500
3
2
2
1
100
100
3
3
1
1
1000
100
2
where
flag1 is number of times flag is 1 for a particular group
flag0 is number of times flag is 0 for a particular group
valFlag1 is sum of flagVal when flag is 1
valFlag0 is sum of flagVal when flag is 0
totalFlags is sum of total flags associated with a group
I am stuck as to how to actually count values based on an IF condition.
Anyhelp is appreciated. Thanks.
I have used a table named group_table with your values
Try using this:
SELECT
g.`groupId`,
SUM(g.`flag`=1 ) AS flag1,
SUM(g.`flag`=0) AS flag0,
SUM(CASE WHEN g.`flag`=1 THEN g.`flagValue` ELSE 0 END) AS valFalg1,
SUM(CASE WHEN g.`flag`=0 THEN g.`flagValue` ELSE 0 END) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`
If you have to use the IF,
SELECT
g.`groupId`,
IF(g.`flag`=1,1,0 ) AS flag1,
IF(g.`flag`=0,1,0) AS flag0,
SUM(IF(g.`flag`=1,g.`flagValue`,0 )) AS valFalg1,
SUM(IF(g.`flag`=0,g.`flagValue`,0 )) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`, flag1, flag0
They'll produce the same result

Sum multiple columns in multiple rows

I have following data structure for sales:
id year M01 M02 M03 M04 M05 M06 M07 M08 M09 M10 M11 M12
1 2020 0 5 4 0 10 0 0 0 0 0 0 0
1 2019 4 3 0 0 6 0 7 0 8 0 0 10
2 2020 0 5 4 0 10 0 0 0 0 0 0 0
2 2019 4 3 0 0 6 0 7 0 8 0 0 10
I need to know how many products with id=1 were sold for the last 12 month. If we are in June 2020 I need to sum M01, M02, M03, M04, M05 (WHERE year=2020) and M06, M07, M08, M09, M10, M11, M12 (WHERE year=2019) WHERE id=1. I should get a value of 36.
Please, any suggestions on how to do that in MySQL?
You need to fix your data model. Unpivot and then aggregate:
with reasonable_format as (
select id, year, str_to_date(concat(year, '-01-01'), '%Y-%m-%d') as date, m01 as amount from sales union all
select id, year, str_to_date(concat(year, '-02-01'), '%Y-%m-%d') as date, m02 from sales union all
. . .
select id, year, str_to_date(concat(year, '-02-01'), '%Y-%m-%d') as date, m12 from sales
)
select sum(amount)
from reasonable_format rf
where id = 1 and date <= curdate - interval 1 year;
reasonable_format is what your data should look like.

MySQL - How to Group by values and display in different colulmn on the same row

I have source table that I would like to sum quantities based on a specific value and display the sum for each value while grouping by an id.
animal_id oh co gender
10 5 1 M
20 10 5 F
10 15 2 F
30 5 0 C
10 5 4 M
20 10 0 F
I need an output of
animal_id Moh Mco Foh Fco Coh Cco
10 10 5 15 2 0 0
20 0 0 20 5 0 0
30 0 0 0 0 5 0
Each column will display the sum of each gender and each row will be grouped by the animal_id.
I tried to use the CASE like is MSSQL but it didn't sum per each gender.
Thinking PIVOT but I'm not very familiar with it.
I'm at a loss...
Try following:
SELECT animal_id,
SUM(IF(gender='M', oh, 0)) AS Moh, SUM(IF(gender='M', co, 0)) AS Mco,
SUM(IF(gender='F', oh, 0)) AS Foh, SUM(IF(gender='F', co, 0)) AS Fco,
SUM(IF(gender='C', oh, 0)) AS Coh, SUM(IF(gender='C', co, 0)) AS Cco
FROM anim_table
GROUP BY animal_id;
So key concept is to combine SUM() with IF()

Sort Data in a Range MySQL

I have a table like below
SUBJECT - MARKS - SEMESTER
MATH - 50 - 1
SCIENCE - 60 - 1
ENGLISH - 70 - 1
MATH - 60 - 2
SCIENCE - 80 - 2
ENGLISH - 90 - 2
I want to produce a output like below. The problem is, even there is no data between 0-10 range I want 0 in all three columns. I am unable to achieve using "group by" and "sum". Do any of you have any idea
RANGE MATH SCIENCE ENGLISH
0-10 0 0 0
10-20 0 0 0
20-30 0 0 0
30-40 0 0 0
40-50 0 0 0
50-60 1 0 0
60-70 1 1 0
70-80 0 0 1
80-90 0 1 0
90-100 0 0 1
You can do this, but you need to define the ranges, either as a reference table or in the query. The rest is conditional aggregation:
select r.range,
sum(subject = 'MATH' and t.marks is not null) as Math,
sum(subject = 'SCIENCE' and t.marks is not null) as Science,
sum(subject = 'English' and t.marks is not null) as English
from ((select 0 as mins, 9.99 as maxs, '0-10' as range) union all
(select 10 as mins, 19.99 as maxs, '10-20' as range) union all
. . .
(select 90 as mins, 100 as maxs, '90-100' as range)
) left join
table t
on t.marks between r.mins and r.maxs
group by r.range
order by min(r.mins);

Enter the same value for the entire year

I have table Payments
Client Dt Payment
1 201311 10
1 201312 0
2 201401 0
1 201402 0
1 201403 0
And i want select where i add to this select column "OwnerFlag", where if the client has paid in that year then in all rows for that year for that client will be OwnerFlag 1, otherwise its 0. So the final select should look like :
Client Dt Payment OwnerFlag
1 201311 10 1
1 201312 0 1
2 201401 0 0
1 201402 0 0
1 201403 0 0
Thank you.
Presuming that DT is a datetime column:
SELECT Client, Dt, Payment,
OwnerFlag = CASE WHEN EXISTS
(
SELECT 1 FROM dbo.Payments p1
WHERE p1.ClientID = p.ClientID
AND YEAR(p1.Dt) = YEAR(p.Dt)
AND p1.Pament <> 0
) THEN 1 ELSE 0 END
FROM dbo.Payments p