Sum qty but result is weird in Mysql - mysql

I'm using MySQL query to sum qty, but the result a little bit weird, this is my query"
SELECT SUM(qty) FROM inventory_logs
WHERE product_id =12 AND `type` = 'is' AND deleted_at IS null
The data I want to sum:
The result:
4.440892098500626e-16
For additional info, the data type qty column is VARCHAR.

So as I mentioned in my comment, you will need to CAST your varchar values into decimal values and then sum them.
This should do the trick:
SELECT
FORMAT(CAST(SUM(qty) AS DECIMAL(12,2)),2) AS qty_sum
FROM
inventory_logs
WHERE
product_id =12 AND `type` = 'is' AND deleted_at IS null
Test fiddle here.

Use this simple trick to make a number of it, but because of the fractal you need also to use a Round for
SELECT ROUND(SUM(qty + 0),2) FROM inventory_logs
WHERE product_id =12 AND `type` = 'is' AND deleted_at IS null
Schema (MySQL v5.7)
CREATE TABLE inventory_logs (
qty VARCHAR(5)
);
INSERT INTO inventory_logs(qty) VALUES('0');
INSERT INTO inventory_logs(qty) VALUES('2.74');
INSERT INTO inventory_logs(qty) VALUES('1.07');
INSERT INTO inventory_logs(qty) VALUES('-3.81');
INSERT INTO inventory_logs(qty) VALUES('3.81');
INSERT INTO inventory_logs(qty) VALUES('-3.81');
Query #1
SELECT ROUND(SUM(qty + 0),2) FROM inventory_logs;
| ROUND(SUM(qty + 0),2) |
| --------------------- |
| 0 |
View on DB Fiddle

Add a 0 to the SUM function it should work:
SELECT SUM(qty + 0) FROM inventory_logs
WHERE product_id =12 AND `type` = 'is' AND deleted_at IS null

Related

MySQL Query to return total hours for state information

I have a mysql table capturing state information for a signal every minute in MySQL table as follows:
ID | state | timestamp |
--------------------------------------
'sig1'| 'red' | '2017-07-10 15:30:21'
'sig1'| 'green' | '2017-07-10 15:31:26'
'sig1'| 'green' | '2017-07-10 15:32:24'
'sig1'| 'red' | '2017-07-10 15:33:29'
'sig1'| 'red' | '2017-07-10 15:34:30'
'sig1'| 'red' | '2017-07-10 15:35:15'
I need to come up with a query where it result should be the most recent time 'sig1' was in 'red' state for more than 5 minutes consecutively, the output of the query should be
ID | state| duration | start_time | end_time
So if you guys can help me with the query, that would be great!
cheers!
You can try something like this:
SELECT t.id,t.consecutive,t.state
,COUNT(*) consecutive_count
,MIN(timestamp) start_time
,MAX(timestamp) end_time
,TIMEDIFF(MAX(timestamp), MIN(timestamp)) AS diff /* for ckeck*/
FROM (SELECT a.* ,
#r:= CASE WHEN #g = a.state AND #h=a.id THEN #r ELSE #r + 1 END consecutive,
#g:= a.state g,
#h:= a.id h
FROM yourtable a
CROSS JOIN (SELECT #g:='', #r:=0, #h:='') t1
ORDER BY id
) t
GROUP BY t.id,t.consecutive,t.state
HAVING (UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(start_time))/60>5
;
Sample data:
CREATE TABLE yourtable (
id VARCHAR(10) NOT NULL ,
state VARCHAR(10) NOT NULL,
timestamp datetime
);
INSERT INTO yourtable VALUES ('sig1','red','2017-07-10 15:30:21');
INSERT INTO yourtable VALUES ('sig1','green','2017-07-10 15:31:26');
INSERT INTO yourtable VALUES ('sig1','green','2017-07-10 15:32:24');
INSERT INTO yourtable VALUES ('sig1','red','2017-07-10 15:33:29');
INSERT INTO yourtable VALUES ('sig1','red','2017-07-10 15:34:30');
INSERT INTO yourtable VALUES ('sig1','red','2017-07-10 15:39:15');
INSERT INTO yourtable VALUES ('sig2','red','2017-07-10 15:15:15');
Output:
id consecutive state consecutive_count start_time end_time diff
sig1 3 red 3 10.07.2017 15:33:29 10.07.2017 15:39:15 00:05:46
SELECT TIMESTAMPDIFF(HOUR,MAXTIME ,MINTIME),ID,state FROM
(
SELECT ID,state,MIN(timestamp)MINTIME,MAX(timestamp) MAXTIME FROM TABLE GROUP BY ID,state
)Z
Try above query.

mysql, query how to goup same value and count that value

i have data table like that :
month IKU value
2 1b 1
2 1b 1
1 2a 1
1 1a 1
the results I want like that :
month IKU value
2 1b 2
1 1a,2a 1,1
is that possible?
You need to use GROUP BY twice along with GROUP_CONCAT function like below:
SELECT
tmp.month,
GROUP_CONCAT(tmp.IKU) AS IKU,
GROUP_CONCAT(tmp.summedValue) AS value
FROM
(
SELECT
month,
IKU,
SUM(value) AS summedValue
FROM t
GROUP BY month,IKU
) AS tmp
GROUP BY tmp.month
ORDER BY tmp.month DESC
GROUP_CONCAT() function
MySQL GROUP_CONCAT() function returns a string with concatenated non-NULL value from a group.
Returns NULL when there are no non-NULL values.
Test:
-- ----------------------------
-- Table structure for `t`
-- ----------------------------
DROP TABLE IF EXISTS `t`;
CREATE TABLE `t` (
`month` int(11) DEFAULT NULL,
`IKU` varchar(10) DEFAULT NULL,
`value` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of t
-- ----------------------------
INSERT INTO `t` VALUES ('2', '1b', '1');
INSERT INTO `t` VALUES ('2', '1b', '1');
INSERT INTO `t` VALUES ('1', '2a', '1');
INSERT INTO `t` VALUES ('1', '1a', '1');
Try this. Didn't get chance to test it as MySQL fiddle isn't working, but the idea is to first sum(value) for each combination of month,iku. Then use group_concat to concatenate the resultset.
select month
,group_concat(IKU separator ',')
,group_concat(value separator ',')
from
(select month,IKU,sum(value) as value
from Table1 group by month,IKU
) t
group by IKU

SQL Arithmetics on rows

I'm trying to find the difference between row 2 and row 1(2-1) for each column,I'm lost on how to approach this, I might be doing this wrong from the beginning for all I know.
The 2 sub queries return the rows I'm interested in and the rest is me trying to put them together in a table to operate operate on them, but needing direction ATM
SELECT ROW_NUMBER() OVER(ORDER BY totalhopper_01 ASC) AS rownum,TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06 FROM
(
SELECT * FROM(
SELECT TOP 1 TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06 FROM mm_Cycle_Data
WHERE TotalHopper_01 IS NOT NULL
AND TotalHopper_02 IS NOT NULL
AND TotalHopper_03 IS NOT NULL
AND TotalHopper_05 IS NOT NULL
AND TotalHopper_06 IS NOT NULL
AND get_address=38 AND t_stamp> '2015-10-28 07:00:00' ORDER BY t_stamp ASC)a
UNION
SELECT * FROM (
SELECT TOP 1 TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06 FROM mm_Cycle_Data
WHERE
TotalHopper_01 IS NOT NULL
AND TotalHopper_02 IS NOT NULL
AND TotalHopper_03 IS NOT NULL
AND TotalHopper_05 IS NOT NULL
AND TotalHopper_06 IS NOT NULL
AND get_address=38 AND t_stamp> '2015-11-17 07:00:00' ORDER BY t_stamp ASC)b
)c
Results
rownum TotalHopper_01 TotalHopper_02 TotalHopper_03 TotalHopper_05 TotalHopper_06
-------------------- -------------- -------------- -------------- -------------- --------------
1 182450272 8343796 2539352 0 0
2 339742596 19222977 4940526 0 0
perhaps create a temp table and populate with required data first then run your query ??
INSERT INTO #TempTable (TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06)
select TOP 1 TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06
FROM mm_Cycle_Data
WHERE TotalHopper_01 IS NOT NULL
AND TotalHopper_02 IS NOT NULL
AND TotalHopper_03 IS NOT NULL
AND TotalHopper_05 IS NOT NULL
AND TotalHopper_06 IS NOT NULL
AND get_address=38 AND t_stamp> '2015-10-28 07:00:00' ORDER BY t_stamp ASC
INSERT INTO #TempTable (TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06)
select TOP 1 TotalHopper_01,TotalHopper_02,TotalHopper_03,TotalHopper_05,TotalHopper_06
FROM mm_Cycle_Data
WHERE TotalHopper_01 IS NOT NULL
AND TotalHopper_02 IS NOT NULL
AND TotalHopper_03 IS NOT NULL
AND TotalHopper_05 IS NOT NULL
AND TotalHopper_06 IS NOT NULL
AND get_address=38 AND t_stamp> '2015-11-17 07:00:00' ORDER BY t_stamp ASC
-- get summary of data
SELECT SUM(TotalHopper_01) as totalHopper_01,SUM(TotalHopper_02) as totalHopper_02
FROM #TempTable
-- clean up the temp table when finished
DROP TABLE #TempTable

Sum only if all grouped rows are not null, else return null

I have a table like this:
item_id quantity
1 2
1 3
2 NULL
2 4
3 NULL
3 NULL
And now I'm doing a SELECT like this:
SELECT
sum(`quantity`) AS `total_quantity`,
FROM `items`
GROUP BY `item_id`
Now, it return repectively 5, 4, and NULL, but I want 5, NULL and NULL.
I want that if there is a NULL value in the grouped rows, the sum should be NULL, and not the sum of the lines whose columns are not null. How can I achieve that?
Thanks!
You can use only case statement to check if any row of a group contains null as quantity
SELECT item_id,
CASE WHEN SUM(quantity IS NULL) > 0
THEN NULL
ELSE SUM(quantity)
END quantity
FROM items
GROUP BY item_id
using #Abhik Chakraborty's fiddle
DEMO
Thats kind if weird output, in most cases the request is to replace null with 0 or something else, however here is a way to do it
select
x.item_id,
max(x.quantity) as quantity from (
SELECT
t1.item_id,
#sm:= if(#prev_item = item_id, #sm_qty+quantity,quantity) as quantity,
#prev_item :=item_id,
#sm_qty:= quantity
from items t1,(select #prev_item:=null,#sm_qty=0)x
order by item_id
)x
group by x.item_id;
http://www.sqlfiddle.com/#!9/ccb36/13
SELECT * FROM (
( -- Get all not null quantities
SELECT
`i1`.`item_id`,
sum(`i1`.`quantity`) AS `total_quantity`
FROM `items` AS `i1`
WHERE `i1`.`item_id` NOT IN ( SELECT `i2`.`item_id` FROM `items` AS `i2` WHERE `i2`.`quantity` IS NULL )
GROUP BY `item_id`
)
UNION ALL
( -- Get all null quantities
SELECT
`i3`.`item_id`,
null AS `i3`.`total_quantity`
FROM `items` AS `i3`
WHERE `i3`.`item_id` IN ( SELECT `i4`.`item_id` FROM `items` AS `i4` WHERE `i4`.`quantity` IS NULL )
GROUP BY `i3.item_id`
)
) AS items_table
ORDER BY items_table.item_id

MySQL multiple COUNTs

I have a table like this:
Fiddle: http://sqlfiddle.com/#!2/44d9e/14
CREATE TABLE IF NOT EXISTS `mytable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(20) NOT NULL,
`money_earned` int(20) NOT NULL,
PRIMARY KEY (`id`)
) ;
INSERT INTO mytable (user_id,money_earned) VALUES ("111","10");
INSERT INTO mytable (user_id,money_earned) VALUES ("111","6");
INSERT INTO mytable (user_id,money_earned) VALUES ("111","40");
INSERT INTO mytable (user_id,money_earned) VALUES ("222","45");
INSERT INTO mytable (user_id,money_earned) VALUES ("222","1");
INSERT INTO mytable (user_id,money_earned) VALUES ("333","5");
INSERT INTO mytable (user_id,money_earned) VALUES ("333","19");
I need to know table has how many rows, how many different users, and how many times each user has earned.
I need this result:
TOTAL_ROWS: 7
TOTAL_INDIVIDUAL_USERS: 3
USER_ID USER_TIMES
111 3
222 2
333 2
Is your problem that you want the total as well? If so, then you can get this using rollup:
SELECT coalesce(cast(user_id as char(20)), 'TOTAL USER_TIMES'),
COUNT(*) as times
FROM mytable
GROUP BY user_id with rollup;
You can get the user counts in a separate column with this trick:
SELECT coalesce(cast(user_id as char(20)), 'TOTAL USER_TIMES'),
COUNT(*) as times, count(distinct user_id) as UserCount
FROM mytable
GROUP BY user_id with rollup;
You realize that a SQL query just returns a table of values. You are asking for very specific formatting, which is typically done better at the application level. That said, you can get close to what you want with something like this:
select user, times
from ((SELECT 3 as ord, cast(user_id as char(20)) as user, COUNT(*) as times
FROM mytable
GROUP BY user_id
)
union all
(select 1, 'Total User Count', count(*)
from mytable
)
union all
(select 2, 'Total Users', count(distinct user_id)
from mytable
)
) t
order by ord;
I think this could be a typo anyway your are trying to sum your COUNT() times, simply replace with money_earned
SELECT user_id,
COUNT(*) AS 'times',
SUM(money_earned) AS 'sum_money'
FROM mytable GROUP BY user_id;
SQL Fiddle