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

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)

Related

When Current column and Previous column > 0, then do this

mysql> select * from table;
+------+------+------+-------+
| id | cnta | cntb | cntc |
+------+-------------+-------+
4 0 1 2
3 2 3 0
2 1 0 1
1 3 2 2
I would like to compare two sequential rows (current column and previous column) and if they are both greater than 0, I'd like to sum the results of the sequential rows.
this is what I tried and failed:
SELECT
g1.id,
(case
When g2.cnta > 0 and g1.cnta > 0 then g1.cnta ELSE 0) End as cnta +
(case
When g2.cntb > 0 and g1.cntb > 0 then g1.cntb ELSE 0) End as cntb +
(case
When g2.cntc > 0 and g1.cntc > 0 then g1.cntc ELSE 0) End as cntc
FROM table g1 INNER JOIN table g2 ON g2.id = g1.id+ 1;
the final output I'm trying to get is like this (if current column and previous column > 0, then current column1 + etc ) :
id totalcnt
4 1
3 2
2 2
1
How can I fix my query? or can I get alternative approach as a solution, please?
** I forgot to mention that there are no NULL values in my table. Only 0s and positive integers.
If your last row of the result is not to be empty, try this:
SELECT
t1.id,
(
CASE WHEN t1.cnta>0 AND t2.cnta>0 THEN t1.cnta ELSE 0 END
+
CASE WHEN t1.cntb>0 AND t2.cntb>0 THEN t1.cntb ELSE 0 END
+
CASE WHEN t1.cntc>0 AND t2.cntc>0 THEN t1.cntc ELSE 0 END
) AS cValue
FROM
table1 t1
LEFT JOIN table1 t2 ON t2.id=t1.id-1;
OR if you really want it to be empty, you can use a subquery
SELECT
t1.id,
IFNULL(
(
SELECT
(
CASE WHEN t1.cnta>0 AND t2.cnta>0 THEN t1.cnta ELSE 0 END
+
CASE WHEN t1.cntb>0 AND t2.cntb>0 THEN t1.cntb ELSE 0 END
+
CASE WHEN t1.cntc>0 AND t2.cntc>0 THEN t1.cntc ELSE 0 END
)
FROM
table1 t2 WHERE t2.id=t1.id-1)
,'') AS cValue
FROM table1 t1
SELECT t1.id,
(t1.cnta * t2.cnta > 0) * t1.cnta
+ (t1.cntb * t2.cntb > 0) * t1.cntb
+ (t1.cntc * t2.cntc > 0) * t1.cntc totalcnt
FROM test t1
LEFT JOIN test t2 ON t1.id = t2.id + 1;
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=48f296035e95bf4c7331427e82c25619
t1.cntX * t2.cntX is NULL if at least one value is NULL, is zero if at least one value is zero, and is 1 if both values are not zero/NULL.

How to calculate weekends of time range using MySQL

I need to calculate weekends of time range using MySQL.
This is what I have so far(about calculate working days but i want to calculate weekends):
select
(floor(days / 7)* 5
+ days%7
- case
when 6 between wd and wd + days%7 - 1 then 1
else 0
end
- case
when 7 between wd and wd + days%7 - 1 then 1
else 0
end) as result
from
(
select
abs(datediff('2022-05-15', '2022-05-13')) + 1 as days,
weekday('2022-05-13') + 1 as wd ) as a;
Hope I explained well...
Thanks.
select
(floor(days / 7)* 2
+ case
when 6 between wd and wd + days%7 - 1 then 1
else 0
end
+ case
when 7 between wd and wd + days%7 - 1 then 1
else 0
end) as result
from ( select
abs(datediff('2022-05-15', '2022-05-13')) + 1 as days,
weekday('2022-05-13') + 1 as wd ) as a;
Maybe this will work. Have a try.

MySQL calculate from same value

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

MYSQL: Get average of fields in case where value is not a certain value

Say I have a table with 5 columns,
A, B, C, D, E
that are integers. I want to get the average of all of the fields in that case, that are not 3.
So, on some sample data:
A, B, C, D, E DESIRED RESULT
-------------
1, 1, 4, 4, 3 -> 2.5 (NOT 2.6)
1, 2, 3, 3, 3 -> 1.5 (NOT 2.4)
EDIT: I found a solution.
(
(
IF(A!=3,A,0)
+IF(B!=3,B,0)
+IF(C!=3,C,0)
+IF(D!=3,D,0)
+IF(E!=3,E,0)
)
/
(
IF(A!=3,1,0)
+IF(B!=3,1,0)
+IF(C!=3,1,0)
+IF(D!=3,1,0)
+IF(E!=3,1,0)
)
) as VALUE
Try that:
select avg(CASE WHEN A = 3 then 0 else A end +
CASE WHEN B = 3 then 0 else B end +
CASE WHEN C = 3 then 0 else C end +
CASE WHEN D = 3 then 0 else D end +
CASE WHEN E = 3 then 0 else E end)/
(CASE WHEN A = 3 then 0 else 1 end +
CASE WHEN B = 3 then 0 else 1 end +
CASE WHEN C = 3 then 0 else 1 end +
CASE WHEN D = 3 then 0 else 1 end +
CASE WHEN E = 3 then 0 else 1 end) as av from table1
group by A,B,C,D,E
DEMO HERE

Calculate values in ranges for every row in table

I have table where some objects are described.
id title low middle high
-- ------- --- ------ ----
1 Object1 2 5 11
2 Object2 2 6 11
3 Object3 2 5 15
4 Object4 2 5 11
5 Object5 2 5 11
6 Object6 2 5 11
7 Object7 2 5 15
So for Object1 values 0…2 should be calculated as lowCount , 3…5 as middleCount, 6…11 as highCount, all values greater than 11 as overCount.
Every object could get 3 values and it’s necessary to count how many values are in low, medium, high and over ranges
So For example with values 1, 4, 12 I expect to get the result
id title low middle high lowCount middleCount highCount overCount
-- ------- --- ------ ---- -------- ----------- --------- ---------
1 Object1 2 5 11 1 0 1 1
2 Object2 2 6 11 1 1 0 1
3 Object3 2 5 15 1 0 2 0
4 Object4 2 5 11 1 0 1 1
5 Object5 2 5 11 1 0 1 1
6 Object6 2 5 11 1 0 1 1
7 Object7 2 5 15 1 0 2 0
For this issue I use the query:
SELECT
`st`.`id`, `st`.`title`, `st`.`low`, `st`.`middle`, `st`.`high`
, (IF((1 >= 0 AND 1 <= `st`.`low`), 1, 0) + IF((4 >= 0 AND 4 <= `st`.`low`), 1, 0) + IF((12 >= 0 AND 12 <= `st`.`low`), 1, 0)) as `lowCount`
, (IF((1 > `st`.`low` AND 1 <= `st`.`middle`), 1, 0) + IF((4 > `st`.`low` AND 4 <= `st`.`middle`), 1, 0) + IF((12 > `st`.`low` AND 12 <= `st`.`middle`), 1, 0)) as `middleCount`
, (IF((1 > `st`.`middle` AND 1 <= `st`.`high`), 1, 0) + IF((4 > `st`.`middle` AND 4 <= `st`.`high`), 1, 0) + IF((12 > `st`.`middle` AND 12 <= `st`.`high`), 1, 0)) as `highCount`
, (IF((1 > `st`.`high`), 1, 0) + IF((4 > `st`.`high`), 1, 0) + IF((12 > `st`.`high`), 1, 0)) + 2 as `overCount`
FROM
`some_table` `st`
I don't like this construction
, (IF((1 >= 0 AND 1 <= `st`.`low`), 1, 0) + IF((4 >= 0 AND 4 <= `st`.`low`), 1, 0) + IF((12 >= 0 AND 12 <= `st`.`low`), 1, 0)) as `lowCount`
What could I use instead
if is acceptable. The case statement is longer, but standard SQL. However, in MySQL, you can also do:
select `st`.`id`, `st`.`title`, `st`.`low`, `st`.`middle`, `st`.`high`,
((1 >= 0 AND 1 <= `st`.`low`) + (4 >= 0 AND 4 <= `st`.`low`) + (12 >= 0 AND 12 <= `st`.`low`)) as `lowCount`,
((1 > `st`.`low` AND 1 <= `st`.`middle`) + (4 > `st`.`low` AND 4 <= `st`.`middle`) + (12 > `st`.`low` AND 12 <= `st`.`middle`)) as `middleCount`,
((1 > `st`.`middle` AND 1 <= `st`.`high`) + (4 > `st`.`middle` AND 4 <= `st`.`high`) + (12 > `st`.`middle` AND 12 <= `st`.`high`)) as `highCount`
FROM `some_table` `st`;
In other words, MySQL treats "true" as 1 and "false" as 0, so you can just add up the boolean values to get the counts.