Im trying to calculate the totale (daily) uptime and the total downtime in MySQL. I got the follow database:
CREATE TABLE `IOT_DATA` (
`DATA_ID` int(11) NOT NULL,
`DATA_BRON` text NOT NULL,
`DATA_SOORT` text NOT NULL,
`DATA_WAARDE` int(11) NOT NULL,
`DATA_TIJD` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `IOT_DATA` (`DATA_ID`, `DATA_BRON`, `DATA_SOORT`, `DATA_WAARDE`, `DATA_TIJD`) VALUES
(931, '77', 'temperature', 29, '2019-06-11 14:05:00'),
(932, '77', 'humidity', 32, '2019-06-11 14:05:00'),
(933, '77', 'temperature', 30, '2019-06-11 14:10:01'),
(934, '77', 'humidity', 32, '2019-06-11 14:10:01'),
(935, '77', 'temperature', 30, '2019-06-11 14:15:00'),
(936, '77', 'humidity', 31, '2019-06-11 14:15:00'),
(963, '77', 'status', 0, '2019-06-11 14:17:19'),
(978, '77', 'status', 1, '2019-06-11 14:18:40'),
(982, '77', 'temperature', 29, '2019-06-11 14:20:00'),
(983, '77', 'humidity', 32, '2019-06-11 14:20:00'),
(993, '77', 'status', 0, '2019-06-11 14:22:40'),
(1008, '77', 'status', 1, '2019-06-11 14:23:21'),
(1019, '77', 'status', 0, '2019-06-11 14:24:50'),
(1044, '77', 'temperature', 30, '2019-06-11 14:25:00'),
(1045, '77', 'humidity', 32, '2019-06-11 14:25:00'),
ALTER TABLE `IOT_DATA`
ADD PRIMARY KEY (`DATA_ID`);
ALTER TABLE `IOT_DATA`
MODIFY `DATA_ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1070;
It saves all sensor data from a machine. The 'DATA_SOORT' "status" indicates if the machine is started (1) or stopped (0).
I do not have a clue where to begin, I searched for comparable topics and got this:
select
date,
DATA_ID,
sum(datediff(minute, starttime, endtime )) downtime
from (
select
cast(t1.DATA_TIJD as date) as date,
t1.serviceid,
min(t1.DATA_TIJD) starttime,
ca.DATA_TIJD endtime
from IOT_DATA t1
cross apply (
select top 1 DATA_TIJD
from IOT_DATA
where serviceid = t1.serviceid
and DATA_TIJD > t1.DATA_TIJD
and DATA_SOORT = "status"
and DATA_WAARDE in (1)
order by DATA_TIJD
) ca
where t1.DATA_ID in (0)
group by cast(t1.DATA_TIJD as date), t1.DATA_ID, ca.DATA_TIJD
) a
group by date, DATA_ID;
It's not working, and honestly have no idea what it is. It gives the follow error:
- Incorrect parameter count in the call to native function 'datediff'
So i searched for that error and got something like it only can handle two expressions? But im not even sure if this is the correct way.
The expected result should be like
+------------+--------+----------+------------+--------------+
| Date | Source | TotaleUp | TotaleDown | PercentageUp |
+------------+--------+----------+------------+--------------+
| 11-06-2019 | 77 | 04:30:20 | 3:30:40 | 56% |
| 12-06-2019 | 77 | 06:00:00 | 1:00:00 | 85% |
+------------+--------+----------+------------+--------------+
The source = DATA_BRON
PercentageUP = Totaleup/(Totaleup+TotaleDown)*100
It is my first topic, if anything is missing please let me know
Related
ds: date in the yyyy/mm/dd format. It is stored in the form of text and we use presto to run. no need for date function
CREATE TABLE job_data(
ds DATE,
job_id INT NOT NULL,
actor_id INT NOT NULL,
event VARCHAR(15) NOT NULL,
language VARCHAR(15) NOT NULL,
time_spent INT NOT NULL,
org CHAR(2) );
INSERT INTO job_data (ds, job_id, actor_id, event, language, time_spent, org)
VALUES ('2020-11-30', 21, 1001, 'skip', 'English', 15, 'A'),
('2020-11-30', 22, 1006, 'transfer', 'Arabic', 25, 'B'),
('2020-11-29', 23, 1003, 'decision', 'Persian', 20, 'C'),
('2020-11-28', 23, 1005,'transfer', 'Persian', 22, 'D'),
('2020-11-28', 25, 1002, 'decision', 'Hindi', 11, 'B'),
('2020-11-27', 11, 1007, 'decision', 'French', 104, 'D'),
('2020-11-26', 23, 1004, 'skip', 'Persian', 56, 'A'),
('2020-11-25', 20, 1003, 'transfer', 'Italian', 45, 'C');
here i have used ds as date datatype.
my code:
select ds, count(job_id) as jobs_per_day, sum(time_spent)/3600 as hours_spent
from job_data
where ds >='2020-11-01' and ds <='2020-11-30'
group by ds ;
This is what I have done but I have to enter date in string and I
can't understand how can I convert it into date without using any
function. I am using mysql workbench 8.0.
You can't convert a string to date without a function . In Presto you can use date_parse. Try:
select cast(date_parse(ds,'%Y-%m-%d') as date) as the_date ,
count(job_id) as jobs_per_day,
sum(time_spent)/3600 as hours_spent
from job_data
where the_date >='2020-11-01' and the_date <='2020-11-30'
group by the_date ;
This question is really confusing me. They didn't provide enough details of it. Whatever they have provided I have written below.
job_id: unique identifier of jobs
actor_id: unique identifier of actor
event: decision/skip/transfer
language: language of the content
time_spent: time spent to review the job in seconds
org: organization of the actor
ds: date in the yyyy/mm/dd format. It is stored in the form of text and we use presto to run. no need for date function
CREATE TABLE job_data
(
ds DATE,
job_id INT NOT NULL,
actor_id INT NOT NULL,
event VARCHAR(15) NOT NULL,
language VARCHAR(15) NOT NULL,
time_spent INT NOT NULL,
org CHAR(2)
);
INSERT INTO job_data (ds, job_id, actor_id, event, language, time_spent, org)
VALUES ('2020-11-30', 21, 1001, 'skip', 'English', 15, 'A'),
('2020-11-30', 22, 1006, 'transfer', 'Arabic', 25, 'B'),
('2020-11-29', 23, 1003, 'decision', 'Persian', 20, 'C'),
('2020-11-28', 23, 1005,'transfer', 'Persian', 22, 'D'),
('2020-11-28', 25, 1002, 'decision', 'Hindi', 11, 'B'),
('2020-11-27', 11, 1007, 'decision', 'French', 104, 'D'),
('2020-11-26', 23, 1004, 'skip', 'Persian', 56, 'A'),
('2020-11-25', 20, 1003, 'transfer', 'Italian', 45, 'C');
Below is the data. Points to be considered :
What does the event mean? What to consider for reviewing?
And here's the query I've tried:
SELECT ds, COUNT(*)/24 AS no_of_job
FROM job_data
WHERE ds BETWEEN '2020-11-01' AND '2020-11-30'
GROUP BY ds;
Check below approach if it is what you are looking for.
select ds,count(job_id) as jobs_per_day, sum(time_spent)/3600 as hours_spent
from job_data
where ds >='2020-11-01' and ds <='2020-11-30'
group by ds ;
Demo MySQL 5.6: https://www.db-fiddle.com/f/7yUJcuMJPncBBnrExKbzYz/26
Demo MySQL 8.0.26: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=83e89a2ad2a7e73b7ca990ac36ae4df0
The difference between the demos as #FaNo_FN pointed out in the comments is: in MySQL 8.0.26version it will provide an error if date 2020-11-31 it is used, because there is no 31 Novembre.
Use and condition instead of between , it performs faster.
You need to sum the time_spent for the day.
I'm creating a badge system for my website: the screenshot below shows you how it looks now. You receive badges with multiple levels (bronze, silver...) after earning 10,100 etc points for specific actions (such as answering a question, correcting a wiki). Note that the looking glass with the dollar sign is there two times, one in silver and one in bronze:
The underlying are two tables, one with the badge informations (x_badges: stores what action and how many points in it gives you what badge level), one with which user has earned which badge (x_badges_earned: badgeID and uID).
Explanation of FKs:
uID is the user ID, passed as parameter (use 1 for tests)
xb_ID is the auto_increment ID for each badge type
xbe_ID is the auto_increment ID of the row that matches userIDs to the ID of the badges they have earned (xb_ID -> uID)
This was my original query, which gives me only one badge of each category (but not the highest, ie if I have earned silver and bronze in one category it'll return only bronze):
SELECT *
FROM x_badges_earned, x_badges
WHERE xbe_bID = xb_ID
AND xbe_uID = ?
GROUP BY xb_requirement
ORDER BY xb_requirement ASC, xb_requirement_value ASC
After research on SO, I created this query which generates the above screenshot. If I change the last GROUP BY to xb_requirement, I'm back with the results from query 1:
SELECT b.*
FROM x_badges b
LEFT JOIN x_badges b2 ON b.xb_ID = b2.xb_ID
AND b.xb_requirement_value < b2.xb_requirement_value
LEFT JOIN x_badges_earned be ON be.xbe_bID = b.xb_ID
WHERE b2.xb_requirement_value IS NULL
AND be.xbe_uID = ?
GROUP BY b.xb_ID
I feel like I'm pretty much going in circles at this moment. I have come up with this which probably would work (at least in my head) but I can't solve it:
SELECT *
FROM x_badges
WHERE xb_ID IN (
SELECT xb_ID, MAX(xb_requirement_value)
FROM x_badges_earned, x_badges
WHERE xbe_bID = xb_ID AND xbe_uID = ?
GROUP BY xb_requirement
)
Any help is greatly appreciated!
I have attached the MySQL code to create the two tables and populate them to play around. Furthermore, you can use 1 as parameter value since it's my userID. My current output looks like this, the desired output would be the same without the first row (xb_ID 11) since it's a bronze badge for which I have earned silver.
CREATE TABLE `x_badges` (
`xb_ID` int(11) NOT NULL,
`xb_requirement` varchar(40) NOT NULL,
`xb_requirement_value` int(11) NOT NULL,
`xb_text` text NOT NULL,
`xb_text_details` text NOT NULL,
`xb_icon` varchar(20) NOT NULL,
`xb_color` varchar(6) NOT NULL,
`xb_color_text` varchar(6) NOT NULL,
`xb_level_name` varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `x_badges` (`xb_ID`, `xb_requirement`, `xb_requirement_value`, `xb_text`, `xb_text_details`, `xb_icon`, `xb_color`, `xb_color_text`, `xb_level_name`) VALUES
(11, 'added_interaction', 10, 'Added interactions', 'Received more than %d points adding interactions with target companies!', 'search-dollar', 'cc8e34', '', 'Bronze'),
(15, 'added_target', 10, 'Added targets', 'Received more than %s points adding target companies!', 'dollar-sign', 'cc8e34', '', 'Bronze'),
(16, 'asked_question', 10, 'Asked questions', 'Received more than %s points asking questions!', 'question', 'cc8e34', '', 'Bronze'),
(17, 'notified_colleagues_interaction', 10, 'Interactions shared with colleagues', 'Received more than %s points tagging colleagues in interactions added!', 'bullhorn', 'cc8e34', '', 'Bronze'),
(18, 'reply_accepted', 10, 'Helpful replies', 'Received more than %s points thanks to replies marked as helpful!', 'check-double', 'cc8e34', '', 'Bronze'),
(19, 'reply_question', 10, 'Replies to questions', 'Received more than %s points replying to questions!', 'comments', 'cc8e34', '', 'Bronze'),
(20, 'updated_info', 10, 'Updated target profiles', 'Received more than %s points updating profiles of targets!', 'funnel-dollar', 'cc8e34', '', 'Bronze'),
(21, 'updated_wiki', 10, 'Updated wiki', 'Received more than %s points updating profiles of Group companies!', 'pen-nib', 'cc8e34', '', 'Bronze'),
(22, 'upvote_question', 10, 'Helpful questions', 'Received more than %s points for having own questions upvoted!', 'grin-alt', 'cc8e34', '', 'Bronze'),
(23, 'added_interaction', 100, 'Added interactions', 'Received more than %s points adding interactions with target companies!', 'search-dollar', 'aaa9ad', '', 'Silver'),
(24, 'added_interaction', 500, 'Added interactions', 'Received more than %s points adding interactions with target companies!', 'search-dollar', 'ffd700', '495057', 'Gold'),
(25, 'updated_wiki', 1000, 'Updated Bertelsmann wiki', 'Received more than %s points asking questions!', 'pen-nib', 'b9f2ff', '495057', 'Diamond'),
(26, 'added_interaction', 1000, 'Added interactions', 'Received more than %s points adding interactions with target companies!', 'search-dollar', 'b9f2ff', '495057', 'Diamond'),
(27, 'added_interaction', 5000, 'Added interactions', 'Received more than %s points adding interactions with target companies!', 'search-dollar', 'e0115f', '', 'Ruby');
CREATE TABLE `x_badges_earned` (
`xbe_ID` int(11) NOT NULL,
`xbe_uID` int(11) NOT NULL,
`xbe_bID` int(11) NOT NULL,
`xbe_timestamp` timestamp NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `x_badges_earned` (`xbe_ID`, `xbe_uID`, `xbe_bID`, `xbe_timestamp`) VALUES
(19, 1, 11, '2020-03-23 15:24:54'),
(20, 1, 15, '2020-03-23 15:24:54'),
(21, 1, 16, '2020-03-23 15:24:54'),
(22, 1, 17, '2020-03-23 15:24:54'),
(23, 1, 18, '2020-03-23 15:24:54'),
(24, 1, 19, '2020-03-23 15:24:54'),
(25, 1, 23, '2020-03-23 16:00:51'),
(26, 1, 20, '2020-03-23 15:32:31'),
(27, 1, 21, '2020-03-23 15:32:31'),
(28, 1, 22, '2020-03-23 15:32:31'),
(29, 10, 25, '2020-03-23 15:37:32');
db<>fiddle here
I have not found identifying expression for any definite badge except (xb_icon, xb_requirement_value) values pair (color is secondary, timestamp not guaranteed the ordering).
So the solution can be:
SELECT *
FROM x_badges xb
JOIN x_badges_earned xbe ON xb.xb_ID = xbe.xbe_bID
JOIN ( SELECT xb.xb_icon, MAX(xb.xb_requirement_value) xb_requirement_value
FROM x_badges xb
JOIN x_badges_earned xbe ON xb.xb_ID = xbe.xbe_bID
WHERE xbe.xbe_uID = #user
GROUP BY xb_icon ) max_earned ON (xb.xb_icon, xb.xb_requirement_value)
= (max_earned.xb_icon, max_earned.xb_requirement_value)
WHERE xbe.xbe_uID = #user;
fiddle
As a recommendation - normalize x_badges table, divide it to 2 separate tables - one stored a badge type data, and another stored level-related data with the reference to first table.
I have the tables:
CREATE TABLE IF NOT EXISTS `buildingAccess` (
`id` int(10) unsigned NOT NULL,
`building` varchar(16) NOT NULL,
`person` varchar(16) NOT NULL,
`enteryDate` datetime NOT NULL,
`exitDate` datetime DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
INSERT INTO `buildingAccess` (`id`, `building`, `person`, `enteryDate`, `exitDate`) VALUES
(1, 'Lot B-3', 'Alice Jones', '2015-11-10 05:29:14', '2015-11-10 15:18:42'),
(3, 'Lot B-3', 'Alice Jones', '2015-11-11 07:11:27', '2015-11-11 12:43:34'),
(7, 'Lot B-3', 'Alice Jones', '2015-12-10 07:11:27', '2015-12-11 12:43:34'),
(2, 'Lot B-3', 'Bill Mayhew', '2015-11-10 10:29:14', '2015-11-10 12:18:42'),
(4, 'Lot B-3', 'Bill Mayhew', '2015-11-12 09:10:27', '2015-11-13 02:43:34'),
(8, 'Lot B-3', 'Bill Mayhew', '2015-11-12 09:10:27', '2015-11-13 02:43:34'),
(5, 'Lot B-3', 'Charlotte Ahn', '2015-12-01 05:29:14', NULL),
(6, 'Lot B-3', 'Dennis Lowe', '2015-12-10 10:29:14', '2015-12-10 12:18:42');
CREATE TABLE IF NOT EXISTS `buildingNotes` (
`building` varchar(16) NOT NULL,
`observer` varchar(16) NOT NULL,
`observationDate` datetime NOT NULL,
`note` varchar(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `buildingNotes` (`building`, `observer`, `observationDate`, `note`) VALUES
('Lot B-3', 'Alice Jones', '2015-11-10 05:32:12', 'burned out light on pole South-22'),
('Lot B-3', 'Alice Jones', '2015-11-10 05:39:12', 'burned out light on pole West-7'),
('Lot B-3', 'Alice Jones', '2015-11-10 05:42:12', 'overfull trash can near pole North-11'),
('Lot B-3', 'Charlotte Ahn', '2015-12-01 06:09:14', 'change drawr running low at gate 3');
ALTER TABLE `buildingAccess`
ADD PRIMARY KEY (`id`), ADD KEY `building` (`building`,`person`,`enteryDate`,`exitDate`);
ALTER TABLE `buildingNotes`
ADD KEY `building` (`building`,`observer`,`observationDate`,`note`);
ALTER TABLE `buildingAccess`
MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=9;
My goal is a query that returns a list of all records in the buildingAccess table. Each should have a notes field that is the GROUP_CONCAT of all of the buildingNotes.note entries made during that record's dates/times bracketed by buildingAccess.enteryDate and buildingAccess.exitDate.
I have tried a few things but am stuck at:
select
BA.building,
BA.person,
BA.enteryDate,
IFNULL(BA.exitDate, NOW()),
IFNULL(
GROUP_CONCAT(
'<p>',
BN.observationDate, ': ',
BN.observer, ': ', BN.note,
'</p>'
ORDER BY BN.observationDate ASC
SEPARATOR ''
),
''
)
from
buildingAccess BA
LEFT JOIN buildingNotes BN ON
BN.building = BA.building
AND BN.observationDate BETWEEN BA.enteryDate AND BA.exitDate
group by BN.building
This returns:
+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| building | person | enteryDate | exitDate | observations |
+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Lot B-3 | Charlotte Ahn | 2015-12-01 05:29:14 | 2016-01-23 23:04:04 | |
| Lot B-3 | Alice Jones | 2015-11-10 05:29:14 | 2015-11-10 15:18:42 | <p>2015-11-10 05:32:12: Alice Jones: burned out light on pole South-22</p><p>2015-11-10 05:39:12: Alice Jones: burned out light on pole West-7</p><p>2015-11-10 05:42:12: Alice Jones: overfull trash can near pole North-11</p> |
+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
I expected to see all of the other buildingAccess records even if there were no buildingNotes records.
I am assuming that I am not "grouping by" the right things but i have not found the right combination yet.
Pointers?
I believe it is due to use BN.building which is from the outer joined table in the GROUP BY clause. Try the following:
SELECT
BA.building
, BA.person
, BA.enteryDate
, IFNULL(BA.exitDate, NOW())
, IFNULL (
GROUP_CONCAT (
'<p>',
BN.observationDate, ': ',
BN.observer, ': ', BN.note,
'</p>'
ORDER BY BN.observationDate ASC
SEPARATOR ''
)
,''
)
FROM buildingAccess BA
LEFT JOIN buildingNotes BN ON BN.building = BA.building
AND BN.observationDate BETWEEN BA.enteryDate AND BA.exitDate
GROUP BY
BA.building
, BA.person
, BA.enteryDate
, IFNULL(BA.exitDate, NOW())
It s possible this is too many rows, and perhaps you need some other way to handle (for example) only getting the date rather than full datetime. However you should routinely specify ALL the non-aggregating columns of a query in the group by caluse. See MySQL GROUP BY Extension
I am having an issue with the code below and my issue is the following:
I need to be able to select the shop_shipping_rule_region_code if the country_iso is NULL but I also need to get the $country_iso data as well if present
What I am after:
The Final Result will have:
Overnight UPS
NZ Snail Mail
Whole World (in this example)
DB:
`shop_shipping_rules` (`shop_shipping_rule_id`, `shop_shipping_rule_country_iso`, `shop_shipping_rule_region_code`, `shop_shipping_rule_name`,
`shop_shipping_rule_type_single`, `shop_shipping_rule_item_single`, `shop_shipping_rule_type_multi`,
`shop_shipping_rule_item_multiple`,`shop_shipping_rule_created`, `shop_shipping_rule_modified`, `website_id`)
VALUES
(41, 'NZ', 'ALL', 'Overnight UPS', 'single', 2.00, 'multi', 4.00, '2013-11-05 02:30:19', '2013-11-05 03:00:27', 64),
(44, 'NZ', NULL, 'NZ Snail Mail', 'single', 25.00, 'multi', 35.00, '2013-11-14 03:57:06', NULL, 64),
(45, NULL, 'ALL', 'Whole World', 'single', 90.00, 'multi', 150.00, '2013-11-14 05:05:53', NULL, 64),
(46, NULL, 'EU', 'EU Ship', 'single', 28.00, 'multi', 35.00, '2013-11-15 01:04:01', NULL, 64);
if (isset($country_iso))
$sql = "SELECT * FROM shop_shipping_rules WHERE country_iso IS NULL OR country_iso = '$country_iso' ";
else
$sql = "SELECT * FROM shop_shipping_rules WHERE country_iso IS NULL";