MySQL calculate from same value - mysql

i have this query:
SELECT `item_code`,
`q_rr`,
`q_srs`,
#running_bal := #running_bal + (`q_rr` - `q_srs`) as `Balance`
FROM records, (SELECT #running_bal := 0) tempName
order by
records.item_code,
records.date
which results is:
item_code | q_rr | q_srs | balance
--------------------------------------------
0F02206A 2 0 2
BR00113D 3 0 5
BR00114D 10 0 15
BR00114D 0 1 14
BR00114D 0 1 13
BR00115D 20 0 33
BR00115D 0 1 32
BR00115D 0 1 31
need help to make the result to calculate the balance, if q_rr(+) and q_srs(-) and calculate per item_code.
item_code | q_rr | q_srs | balance
--------------------------------------------
0F02206A 2 0 2
BR00113D 3 0 3
BR00114D 10 0 10
BR00114D 0 1 9
BR00114D 0 1 8
BR00115D 20 0 20
BR00115D 0 1 19
BR00115D 0 1 18

I added #code variable to track item_code changes:
SELECT
r.item_code,
r.q_rr,
r.q_srs,
#running_bal := IF(#code = r.item_code, #running_bal, 0) + (r.q_rr - r.q_srs) as Balance,
#code := r.item_code AS dummy
FROM
records r
CROSS JOIN
(SELECT #running_bal := 0, #code := '') tempName
ORDER BY
r.item_code,
r.date
SQL Fiddle: http://sqlfiddle.com/#!2/04ef2b/11
You can eliminate dummy column by putting this as subquery in another select:
SELECT item_code, q_rr, q_srs, Balance
FROM (
-- there put first query
) r
SQL Fiddle: http://sqlfiddle.com/#!2/04ef2b/12

Try this:
SELECT `item_code`,
`id`,
`type`,
#running_bal := case when type = 0 then id
else #running_bal + (`id` - `type`) end as `Balance`
FROM supportContacts, (SELECT #running_bal := 0) tempName
order by
supportContacts.item_code
SQL FIDDLE

Related

The minimum value from each category

I want to get out the minimum price for categories 1, 2 and 3
I've used
LEAST(MIN(price_reduced),MIN(price))
IFNULL(MIN(price_reduced),MIN(price)) ... WHERE price <> 0 and price_reduced <> 0
Database
id
category
price
price_reduced
1
1
200
100
2
1
300
0
3
1
500
0
4
2
200
150
5
2
125
0
6
3
300
0
7
3
200
90
Output
1 - 100
2 - 125
3 - 90
Thank you
This query will work on all MySQL V4+ :
SELECT Category,
MIN(IF((price_reduced > 0) AND (price_reduced < price), price_reduced, price)) AS P
FROM your_table GROUP BY Category;
Maybe with cte:
WITH cte AS (SELECT category,
MIN(price) AS mp,
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END) pr
FROM mytable
GROUP BY category)
SELECT category, LEAST(mp, pr) AS min_val
FROM cte;
Or without cte but with derived table:
SELECT category, LEAST(mp, pr) AS min_val
FROM (SELECT category,
MIN(price) AS mp,
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END) pr
FROM mytable
GROUP BY category) a;
Or just a single query:
SELECT category,
LEAST(MIN(price),
MIN(CASE WHEN price_reduced <= 0 THEN 9999 ELSE price_reduced END)) AS min_val
FROM mytable
GROUP BY category;
All return the same results.
Demo fiddle

How to use sum over partition (withhout window function) in mysql 5.7

I want to know how mysql 5.7 engine works the same as sum over part.
Cannot replace query engine because it is not a personal operation.
There was an attempt to resolve it through the #set variable function, but I find it difficult to get a cumulative sum for each of the four columns.
I looked at the link below, but it was a little bit difficult to resolve.
how to rank over partition in MySql
My table
id a b c d
----------------------------
abs 1 0 0 1
abs 0 1 1 0
abs 1 0 1 0
abs 1 1 1 1
qwe 0 0 0 0
qwe 0 0 0 1
qwe 1 0 1 0
qwe 1 1 0 1
trx 0 1 1 0
trx 1 1 0 0
Expected
id a b c d
----------------------------
abs 1 0 0 1
abs 1 1 1 1
abs 2 1 2 1
abs 3 2 3 2
qwe 0 0 0 0
qwe 0 0 0 1
qwe 1 0 1 1
qwe 2 1 1 2
trx 0 1 1 0
trx 1 2 1 0
Thanks in advance.
You want cumulative sums for each column. In order for this to work, you need a column that specifies the ordering -- SQL tables represent unordered sets.
Assuming you have such a column, then the following would often work:
select t.*,
(#a := if(#id = id, #a + a, 0)) as a,
(#b := if(#id = id, #b + b, 0)) as b,
(#c := if(#id = id, #c + c, 0)) as c,
(#d := if(#id = id, #d + d, 0)) as d,
#id := id
from (select t.*
from t
order by t.id, ? -- column for the ordering
) t cross join
(select #id := -1, #a := 0, #b := 0, #c := 0 #d := 0) params;
However, this is not guaranteed to work, because MySQL does not guarantee the order of evaluation of expressions in a SELECT. So, I think subqueries might be the simplest method:
select t.id,
(select sum(t2.a) from t t2 where t2.id = t.id and t2.? <= t.?) as a,
(select sum(t2.b) from t t2 where t2.id = t.id and t2.? <= t.?) as b,
(select sum(t2.c) from t t2 where t2.id = t.id and t2.? <= t.?) as c,
(select sum(t2.d) from t t2 where t2.id = t.id and t2.? <= t.?) as d
from t;

MySQL Rolling Subtraction of a given qantity

I have a table like this:
CREATE TABLE `PQ_batch` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Batch Id number',
`date` datetime DEFAULT NULL,
`qty` int(11) DEFAULT NULL COMMENT 'Number of units in a batch',
PRIMARY KEY (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;
Id | date | qty
--------------------------------
1 2017-01-06 5
2 2017-01-02 5
3 2017-01-03 100
Given a qty value of: #qtyToTake:=100
*Select the rows that will be needed to fulfill the #qtyToTake and ONLY these rows, the quantity that is to be taken from each row, and the new quantity that remains for that row. The oldest batches should be used up first. *
It should look something like this:
Id | date | qty | newQty | qtyTakenPerRecord
-------------------------------------------------------
1 2017-01-02 5 0 5
2 2017-01-03 100 5 95
3 2017-01-01 5 5 0
newQty = (qty - #qtyToTake) where #qtyToTake = (#qtyToTake - the previous row's qty until #qtyToTake reaches 0)
#qtyToTake should be dynamically assigned to be the difference of the previous row's qty and its current value until it reaches 0.
Here's what I came up with:
SELECT p.bid, p.Orig as origQty, p.NewQty, (p.Orig - p.NewQty) AS NumToTake
FROM(
SELECT b.bid, (#runtot := b.bqty - #runtot) AS remain, ( #runtot := (b.bqty - #runtot) ) leftToGet, b.bqty AS Orig,
(SELECT
(sum(bqty) - #runtot) AS tot FROM PQ_batch
WHERE bid <= b.bid ) AS RunningTotal,
(SELECT
CASE
WHEN (sum(bqty) - #runtot) > 1 THEN (sum(bqty) - #runtot)
ELSE 0
END
FROM PQ_batch
WHERE bid <= b.bid ) AS NewQty
FROM PQ_batch b,(SELECT #runtot:= 100) c
ORDER BY bdate
) AS p
Using #McNets example here's what I came up with:
SELECT bid, bdate,bpid,bcost, bqty, newQty, qtyTakenPerRecord
FROM (
SELECT y.*,
IF(#qtyToTake > 0, 1, 0) AS used,
IF(#qtyToTake > bqty, 0, bqty - #qtyToTake) AS newQty,
IF(#qtyToTake > bqty, bqty, bqty - (bqty - #qtyToTake)) AS qtyTakenPerRecord,
#qtyToTake := #qtyToTake - bqty AS qtyToTake
FROM
(SELECT #qtyToTake := 100) x,
(SELECT * from PQ_batch WHERE bpid =1002 AND bqty > 0 ORDER BY bdate) y
) z
WHERE used = 1
ORDER BY bdate

count multiple columns in one query

Guys i have four queries:
Query #1:
select
satisfaction_score,count(satisfaction_score) as Satisfaction_count
from j_survey_response
where satisfaction_score != 0
group by satisfaction_score
The output will be
satisfaction_score Satisfaction_count
1 5
2 8
3 97
4 329
5 859
Query #2:
select
response_score,count(response_score) as response_count
from j_survey_response
where response_score != 0
group by response_score
OUTPUT
response_score response_count
1 28
2 8
3 42
4 250
5 980
Query #3:
select
responder_score,count(responder_score) as responder_count
from j_survey_response
where responder_score != 0
group by responder_score
OUTPUT
responder_score responder_count
1 24
2 3
3 30
4 236
5 987
Query #4:
select
service_score,count(service_score) as service_count
from j_survey_response
where service_score != 0
group by service_score
OUTPUT
service_score service_count
1 22
2 2
3 34
4 270
5 966
But I need the output as below
score satisfaction_count response_count responder_count service_count
1 5 28 24 22
2 8 8 3 2
3 97 42 30 34
4 329 250 236 270
5 859 980 986 966
You can UNION ALL the separate queries and apply conditional aggregation on the resulting set:
select score,
max(case when type = 'satisfaction' then count end) as satisfaction_count,
max(case when type = 'response' then count end) as response_count,
max(case when type = 'responder' then count end) as responder_count,
max(case when type = 'service' then count end) as service_count
from (
select satisfaction_score as score,
count(satisfaction_score) as count,
'satisfaction' as type
from j_survey_response
where satisfaction_score != 0
group by satisfaction_score
union all
select response_score,
count(response_score) as count, 'response' as type
from j_survey_response
where response_score != 0
group by response_score
union all
select responder_score,
count(responder_score) as count, 'responder' as type
from j_survey_response
where responder_score != 0
group by responder_score
union all
select service_score,
count(service_score) as count, 'service' as type
from j_survey_response
where service_score != 0
group by service_score) as t
group by score
Move them in subqueries and join them by score columns. Like this
select
q1.satisfaction_score as score,
q1.satisfaction_count,
q2.response_count,
q3.responder_count ,
q4.service_count,
from (query 1) q1
join (query 2) q2 on q1.satisfaction_score=q2.response_score
join (query 3) q3 on q1.satisfaction_score=q3.responder_score
join (query 4) q4 on q1.satisfaction_score=q3.service_score
You Try this Sql Query
select service_score , count(satisfaction_score) as Satisfaction_count,
count(response_score) as response_count,count(responder_score) as `responder_count,
count(service_score) as service_count from j_survey_response
where service_score != 0 and responder_score != 0 and response_score != 0 and satisfaction_score != 0`
if you use group by
select service_score , count(satisfaction_score) as Satisfaction_count,
count(response_score) as response_count,count(responder_score) as `responder_count,
count(service_score) as service_count from j_survey_response
where service_score != 0 and responder_score != 0 and response_score != 0 and satisfaction_score != 0`
group by satisfaction_score,response_score,responder_score,service_score

MYSQL select rows when criteria in at least x colums is met?

Another MYSQL question where I could not find an answer:
I have this table and I want to to get all ID's which have SN>7 AND reps > 4 and where in columns 1-6 a certain criteria is met at least x times.
For example where at least 3 cells in columns col1-col6 have a value > 1.
The first part is easy (SELECT * FROM table WHERE SN > 7 AND reps > 4....) but I can't figure out second part.
Thanks!
ID SN reps col1 col2 col3 col4 col5 col6
A 12 3 0.6 1 3 -2 1 3
B 6 5 3.2 1.1 -3.3 3 0 0
C 300 6 1.3 -0.4 0 0.6 -0.5 -3.3
Try:
SELECT * FROM table
WHERE SN > 7 AND reps > 4 and
(case when `1` > 1 then 1 else 0 end +
case when `2` > 1 then 1 else 0 end +
case when `3` > 1 then 1 else 0 end +
case when `4` > 1 then 1 else 0 end +
case when `5` > 1 then 1 else 0 end +
case when `6` > 1 then 1 else 0 end) >= 3
select * from table where sn> 7 and reps > 4 and
(((`1` > 1) + (`2` > 1 ) + (`3` > 1) + (`4` > 1) + (`5` >1 ) + (`6` > 1)) >= 3)