MySQL calculating only first row - mysql

I have table that have stored date time...i need using mysql to calculate duration in 0d 0h 0m 0s format to show it in datatables:
+----+---------------------+
| id | playtime |
+----+---------------------+
| 2 | 08:58:24 20/06/2017 |
| 1 | 08:57:33 20/06/2017 |
+----+---------------------+
This is my query:
SELECT (SELECT GROUP_CONCAT(
TIMESTAMPDIFF(day, live.playtime, NOW()) , 'd ',
MOD(TIMESTAMPDIFF(hour, live.playtime, NOW()), 24), 'h ',
MOD(TIMESTAMPDIFF(minute, live.playtime, NOW()), 60), 'm ',
MOD(TIMESTAMPDIFF(second, live.playtime, NOW()), 60), 's'
) FROM live) AS duration;
The problem is that only first id is calculated and others ids are ignored....how can i return multiple result for each id calulated time?
I need to return this:
+-----------------------------+
| duration |
+-----------------------------+
| 0d 0h 13m 50s,0d 0h 12m 59s |
+-----------------------------+
| 0d 0h 11m 12s,0d 0h 6m 9s |
+-----------------------------+
UPDATED FULL QUERY:
SELECT SQL_CALC_FOUND_ROWS live.id, live.user, live.player,
SUBSTRING_INDEX(streams.channel, '_', -1) AS channel, bouquets.bouquet,
DATE_FORMAT(live.playtime, '%H:%i:%s %d/%m/%Y') AS playtime,
(SELECT CONCAT(
TIMESTAMPDIFF(day, live.playtime, NOW()) , 'd ',
MOD(TIMESTAMPDIFF(hour, live.playtime, NOW()), 24), 'h ',
MOD(TIMESTAMPDIFF(minute, live.playtime, NOW()), 60), 'm ',
MOD(TIMESTAMPDIFF(second, live.playtime, NOW()), 60), 's'
) FROM live GROUP BY live.id LIMIT 1) AS duration,
resellers.nick, live.ip, servers.server, live.id, live.id
FROM live LEFT JOIN streams ON live.stream=streams.id LEFT JOIN bouquets ON
live.bouquet=bouquets.id LEFT JOIN resellers ON live.reseller=resellers.id
LEFT JOIN servers ON live.server=servers.id
ORDER BY live.id desc LIMIT 0, 10;

Assuming there is only one record per id, could you try adding a WHERE clause in nested SELECT query, e.g.:
SELECT SQL_CALC_FOUND_ROWS live.id, live.user, live.player,
SUBSTRING_INDEX(streams.channel, '_', -1) AS channel, bouquets.bouquet,
DATE_FORMAT(live.playtime, '%H:%i:%s %d/%m/%Y') AS playtime,
(SELECT CONCAT(
TIMESTAMPDIFF(day, l.playtime, NOW()) , 'd ',
MOD(TIMESTAMPDIFF(hour, l.playtime, NOW()), 24), 'h ',
MOD(TIMESTAMPDIFF(minute, l.playtime, NOW()), 60), 'm ',
MOD(TIMESTAMPDIFF(second, l.playtime, NOW()), 60), 's'
) FROM live l WHERE l.id = live.id) AS duration,
resellers.nick, live.ip, servers.server, live.id, live.id
FROM live LEFT JOIN streams ON live.stream=streams.id LEFT JOIN bouquets ON
live.bouquet=bouquets.id LEFT JOIN resellers ON live.reseller=resellers.id
LEFT JOIN servers ON live.server=servers.id
ORDER BY live.id desc LIMIT 0, 10;

Related

SQL group by school name

school_name
class
medium
total
srk
1
english
13
srk
2
english
14
srk
3
english
15
srk
1
french
16
srk
2
french
16
srk
3
french
18
vrk
1
english
17
vrk
1
french
18
I want that output by
school_name
class1eng
class1french
class2eng
class2french
class3english
class3french
[output needed][ otput required
output
You’re looking for multiple select statements along with appropriate cases to satisfy.
This should work for you
Select
school_name,
Sum(Case when (class=1 and medium=‘English’) then total else 0 end) as class1english,
Sum(Case when (class=1 and medium=‘French’) then total else 0 end) as class1french,
Sum(Case when (class=2 and medium=‘English’) then total else 0 end) as class2english,
Sum(Case when (class=2 and medium=‘French’) then total else 0 end) as class2french,
Sum(Case when (class=3 and medium=‘English’) then total else 0 end) as class3english,
Sum(Case when (class=3 and medium=‘French’) then total else 0 end) as class3french
From
table_name
Group by
school_name
Seems to be a simple ask, assumed you also want to order your results. Please check below query if that helps
SELECT school_name, class, medium, SUM(total) AS Total
FROM <Table Name>
GROUP BY school_name, class, medium
This solution is for general purpose, complex, but functional.
I've made it for myself as exercise and challenge.
/* --------------- TABLE --------------- */
CREATE TABLE schools_tab
(school VARCHAR(9), class INT, subj VARCHAR(9), total INT);
INSERT INTO schools_tab VALUES
('srk', 1, 'english', 13),
('srk', 2, 'english', 14),
('srk', 3, 'english', 15),
('srk', 1, 'french', 16),
('srk', 2, 'french', 16),
('srk', 3, 'french', 18),
('vrk', 1, 'english', 17),
('vrk', 1, 'french', 18);
/* -------------- DYNAMIC QUERY --------------- */
SET #sql=NULL;
WITH cte AS (
SELECT school, class, subj, ROW_NUMBER() OVER (PARTITION BY school) AS idx, DENSE_RANK() OVER (ORDER BY school) AS ids
FROM (SELECT DISTINCT school FROM schools_tab) A LEFT JOIN (SELECT DISTINCT class, subj FROM schools_tab) B ON (1=1)
), cte2 AS (
SELECT A.ids, A.idx, A.school, A.class, A.subj, COALESCE(B.total, 0) AS total
FROM cte A LEFT JOIN schools_tab B ON (A.school=B.school AND A.class=B.class AND A.subj=B.subj)
), cte3 AS (
SELECT DISTINCT class, subj
FROM schools_tab
ORDER BY class, subject
)
SELECT CONCAT('WITH RECURSIVE cte AS (
SELECT school, class, subj, ROW_NUMBER() OVER (PARTITION BY school) AS idx, DENSE_RANK() OVER (ORDER BY school) AS ids
FROM (SELECT DISTINCT school FROM schools_tab) A LEFT JOIN (SELECT DISTINCT class, subj FROM schools_tab) B ON (1=1)
), cte2 AS (
SELECT A.ids, A.idx, A.school, A.class, A.subj, COALESCE(B.total, 0) AS total
FROM cte A LEFT JOIN schools_tab B ON (A.school=B.school AND A.class=B.class AND A.subj=B.subj)
), ctx AS ('
'SELECT (SELECT MAX(ids) FROM cte2) AS n,',
GROUP_CONCAT(DISTINCT CONCAT( '(SELECT total FROM cte2 WHERE idx=',idx,' AND ids=n) AS class',class,subj ) ORDER BY class, subj),
' UNION ALL SELECT n-1 AS n,',
GROUP_CONCAT(DISTINCT CONCAT( '(SELECT total FROM cte2 WHERE idx=',idx,' AND ids=n) AS class',class,subj ) ORDER BY class, subj),
' FROM ctx WHERE n>0',
') SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(''srk,vrk'', '','', n+1), '','', -1) AS school,',
GROUP_CONCAT(DISTINCT CONCAT('class',class,subj)),
' FROM ctx ORDER BY school'
) INTO #sql
FROM cte2;
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;

Dynamically count values in column, grouped by months

I'm trying to get a single mySQL query that returns the count of unique values, grouped by months.
I have a table created based on data similar to this:
CREATE TABLE `animals` (
`timestamp` datetime NOT NULL,
`animal` tinytext NOT NULL,
`comment` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `animals` (`timestamp`, `animal`, `comment`) VALUES
('2019-06-03 09:09:00', 'dog', 'good'),
('2019-06-03 12:00:00', 'cat', ''),
('2019-06-03 19:00:00', 'cat', ''),
('2019-07-04 09:00:00', 'cat', ''),
('2019-07-04 12:00:00', 'cat', 'feisty'),
('2019-07-04 18:51:00', 'dog', ''),
('2019-08-05 09:00:00', 'cat', ''),
('2019-08-05 12:00:00', 'cat', ''),
('2019-08-05 19:00:00', 'cat', ''),
('2019-09-06 09:00:00', 'cat', ' evil'),
('2019-09-06 12:00:00', 'cat', ''),
('2019-09-06 19:00:00', 'cat', '')
I've managed to write a query that at least gives me the count per month (as long as it is more than zero), but the query just returns the count for "cat", "dog" or anything I explicitly ask for.
My goal is to get a response similar to the following:
month | dog | cat
-------------------
2019-06 | 1 | 2
2019-07 | 1 | 2
2019-08 | 0 | 3
2019-09 | 0 | 3
How do I writhe such a query?
Is it possible to write a query that automatically counts any new values in the animal column too?
Thanks
You can use the following code, to get flexible columns from the animal column
, that does the counting for you.
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'Sum(`animal` = ''',
col,
''') as `',
col, '`')
) INTO #sql
FROM
(
select animal col
from animals
)d;
SET #sql = CONCAT('SELECT date_format(`timestamp`, "%Y-%m") `month`, ', #sql, '
from `animals`
group by `month`
order by `month`');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Se dbfiddle example https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=09d0f26087d66452fde1a22e91de7b3a
You can have
SELECT date_format(`timestamp`, '%Y-%m') AS month, animal, COUNT(*) as count
FROM animals
GROUP BY 1, 2
but this won't give you dynamically more columns. For more columns, I guess you need to build a dynamic SQL command looping over the distinct animals you have. If you really need this, you should consider to build that gives you the SQL string or directly the result.
You want conditional aggregation:
select
date_format(`timestamp`, '%Y-%m') `month`,
sum(`animal` = 'dog') dog,
sum(`animal` = 'cat') cat
from `animals`
group by `month`
order by `month`
Demo on DB Fiddle:
month | dog | cat
:------ | --: | --:
2019-06 | 1 | 2
2019-07 | 1 | 2
2019-08 | 0 | 3
2019-09 | 0 | 3
If you want to handle dynamically the column list, then you have to go for dynamic sql:
set #sql = null;
select
concat(
'select ',
'date_format(`timestamp`, ''%Y-%m'') `month`, ',
group_concat(
concat(
'sum(`animal` = ''',
`animal`,
''') ',
`animal`
)
order by `animal`
separator ', '
),
' from `animals` ',
'group by `month` '
'order by `month`'
)
into #sql
from (
select distinct `animal` from `animals`
) t;
select #sql;
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;

How to show multiple condition with mysql

I have a problem with with my query. I have this data : Check this out here is full data and my table. http://sqlfiddle.com/#!9/f440d7/1
Please i hope you can help me.
My expected result should be like this :
|PartID | IdMesin |ket1 |ket2 |Ket3|
|---------- |-------- |---------------- |---------| |
|AELE-00071-XX-KGX|BS 150U |- |1.00 Tes1|- |
|GCXX-MX070-XX-KGX|BS 320F |0.50 Tes3, 2.00 Tes4|0.50 Tes2|- |
I hope you can help me to fix this problem. Anyhelp can be appreciated.
case when should be used in group_concat:
SELECT partid,
idmesin,
COALESCE(GROUP_CONCAT(CASE WHEN idshift = '1' THEN CONCAT(ROUND(
TIME_TO_SEC(
MAKETIME(
durasi + 0,
SUBSTRING_INDEX(durasi, 'Jam ', - 1) + 0, 0)) / 3600, 2), ' ',
keterangandowntime) end), '-') ket1,
COALESCE(GROUP_CONCAT(CASE WHEN idshift = '2' THEN CONCAT(ROUND(
TIME_TO_SEC(
MAKETIME(
durasi + 0,
SUBSTRING_INDEX(durasi, 'Jam ', - 1) + 0, 0)) / 3600, 2), ' ',
keterangandowntime) end), '-') ket2,
COALESCE(GROUP_CONCAT(CASE WHEN idshift = '3' THEN CONCAT(ROUND(
TIME_TO_SEC(
MAKETIME(
durasi + 0,
SUBSTRING_INDEX(durasi, 'Jam ', - 1) + 0, 0)) / 3600, 2), ' ',
keterangandowntime) end), '-') ket3
FROM trans_lhpdtdw
WHERE divisiid = 'IJ001'
AND tanggal = '2017-11-20'
AND idlocation LIKE '%3%'
GROUP BY partid,
idmesin
See demo in SQLFiddle.

Getting max value in a specific peroid of time in MySQL

I have a table like this(tblFuel):
time fuel
2014-11-04 17:11:08 231
2014-11-04 17:34:16 254
2014-11-04 18:03:48 241
2014-11-04 18:41:34 137
2014-11-04 18:43:42 111
Now I expect to show the biggest value of fuel during each 1 hour. For example: max from 17:00:00 to 17:59:59 and so on. And follow the previous requirement, the expected result should:
time fuel
2014-11-04 17:34:16 254
2014-11-04 18:03:48 241
So what should I do to achieve this result?
create table tblFuel (time timestamp, fuel int);
insert into tblFuel values ('2014-11-04 17:11:08', 231);
insert into tblFuel values ('2014-11-04 17:34:16', 254);
insert into tblFuel values ('2014-11-04 18:03:48', 241);
insert into tblFuel values ('2014-11-04 18:41:34', 137);
insert into tblFuel values ('2014-11-04 18:43:42', 111);
select
*
from tblFuel
where concat(date(time), hour(time), fuel) in
(select
concat(date(time), hour(time), max(fuel))
from tblFuel
group by
date(time),
hour(time))
Returns:
time fuel
2014-11-04 17:34:16 254
2014-11-04 18:03:48 241
This query will be helpful.
DECLARE #tblFuel TABLE
(
Val INTEGER,
Time DATETIME
)
INSERT INTO #tblFuel
SELECT '231', '2014-11-04 17:11:08' union All
SELECT '254', '2014-11-04 17:34:16' union All
SELECT '241', '2014-11-04 18:03:48' union All
SELECT '137', '2014-11-04 18:41:34' union All
SELECT '111', '2014-11-04 18:43:42'
SELECT A.Val, A.Time FROM #tblFuel AS A
Inner join
(SELECT MAX(Val) AS VAL,
CONVERT(VARCHAR(20), Time, 110) +' ' + CAST(DATEPART(hour, Time) as varchar(2)) AS Time
FROM #tblFuel GROUP BY CONVERT(VARCHAR(20), Time, 110) +' ' + CAST(DATEPART(hour, Time) as varchar(2))) AS B
ON A.Val = B.val AND CONVERT(VARCHAR(20), A.Time, 110) +' ' + CAST(DATEPART(hour, A.Time) as varchar(2)) = B.Time
Here's one way to do it. It uses the DATE_FORMAT function to group by date and hour.
SELECT ft.time, ft.fuel
FROM fuel_table ft
JOIN
(SELECT DATE_FORMAT(time, '%Y%m%d %H') date_and_hour, MAX(fuel) max_fuel
FROM fuel_table
GROUP BY date_and_hour) AS max_fuel
ON DATE_FORMAT(ft.time, '%Y%m%d %H') = max_fuel.date_and_hour
AND ft.fuel = max_fuel

mysql select all calculate difference bewteen multiple rows to on result from pivot

I have an pivot table from an root table here on SQL Fiddle, this link: pivot operation
Here I try to calculate the difference between "Arbeitszeit", "Arbeitsende" and between "Projektzeit" and "Projektende".
The problem is, if there is more than one value, the calculation does not work, like this:
19.06.2013 07:27:27,19.06.2013 09:08:58
I need the data either seperated or in best case, merged to see just the result of the differnces.
There is no possibility to get the root data in any other way because this is generated by an interface-
I am assuming that the data is coming in the concatenated form -- not that you are created it. You can unconcatenate it using substring_index() and reverse(), along with a table that generates numbers.
The following query undoes the concatenate, then groups the results back together:
select t.*,
sum(HOUR(TIMEDIFF(STR_TO_DATE(Arbeitsbeginn, '%d.%m.%Y %H:%i:%s'), STR_TO_DATE(Arbeitsende, '%d.%m.%Y %H:%i:%s')))) AS ARBEITSZEIT,
sum(HOUR(TIMEDIFF(STR_TO_DATE(Projektbeginn, '%d.%m.%Y %H:%i:%s'), STR_TO_DATE(Projektbeginn, '%d.%m.%Y %H:%i:%s')))) AS Projektzeit
FROM (select DriverName,
(case when n.n = 1 then substring_index(arbeitsbeginn, ',', 1)
else reverse(substring_index(REVERSE(substring_index(arbeitsbeginn, ',', 2)), ',', 1))
end) as arbeitsbeginn,
(case when n.n = 1 then substring_index(arbeitsende, ',', 1)
else reverse(substring_index(REVERSE(substring_index(arbeitsende, ',', 2)), ',', 1))
end) as arbeitsende,
(case when n.n = 1 then substring_index(Projektbeginn, ',', 1)
else reverse(substring_index(REVERSE(substring_index(Projektbeginn, ',', 2)), ',', 1))
end) as Projektbeginn,
(case when n.n = 1 then substring_index(Projektbeginn, ',', 1)
else reverse(substring_index(REVERSE(substring_index(ProjektEnde, ',', 2)), ',', 1))
end) as ProjektEnde
from (SELECT DRIVERNAME,
GROUP_CONCAT(IF(ACTIONTEXT = 'Arbeitsbeginn', DATETIME, NULL)) AS 'Arbeitsbeginn',
GROUP_CONCAT(IF(ACTIONTEXT = 'Arbeitsende', DATETIME, NULL)) AS 'Arbeitsende',
GROUP_CONCAT(IF(ACTIONTEXT = 'PB', DATETIME, NULL)) AS 'Projektbeginn',
GROUP_CONCAT(IF(ACTIONTEXT = 'PE', DATETIME, NULL)) AS 'Projektende'
FROM geoImportRoot
GROUP BY DRIVERNAME
) A cross join
(select 1 as n union all select 2) n
) t
group by DriverName