Convert and round (Seconds to Minutes) with SQL - mysql

I have a field on my table which represents seconds, I want to convert to minutes
Select (100/60) as Minute from MyTable
-> 1.66
How can I get 1 minute and 40 seconds 00:01:40 and then round to 00:02:00 and if 00:01:23 round to 00:01:30
Using Mysql.

There are two ways of rounding, using integer arithmetic and avoiding floating points, a value to the nearest thirty seconds...
((seconds + 15) DIV 30) * 30
(seconds + 15) - (seconds + 15) % 30
The latter is longer, but in terms of cpu time should be faster.
You can then use SEC_TO_TIME(seconds) to get the format hh:mm:ss, and take the right 5 characters if you really need hh:mm.
If you wanted to avoid SEC_TO_TIME(seconds), you can build up the string yourself.
minutes = total_seconds DIV 60
seconds = total_seconds % 60
final string = LPAD(minutes, 2, '0') | ':' | LPAD(seconds, 2, '0')

i am not sure about how to round it but you can convert seconds into time i.e hh:mm:ss format using SEC_TO_TIME(totaltime)

Desired result :
A = 30
B = 60
C = 90
D = 120
select
(25 + 15)-(25 + 15) % 30 as A,
(32 + 15)-(32 + 15) % 30 as B,
(90 + 15)-(90 + 15) % 30 as C,
(100 + 15)-(100 + 15) % 30 as D
Result :
A = 30
B = 30
C = 90
D = 90
I try with this:
select
30* ceil(30/30) as A,
30* ceil(32/30) as B,
30* ceil(90/30) as C,
30* ceil(100/30) as D
Result :
A = 30
B = 60
C = 90
D = 120
Thank you for your help !

You can simply write your own function http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
But I'd rather do that in a programing language (PHP, Python, C), not on the database side.

Related

from and to ranges in mysql

Currently I have this kind of query
SELECT
part_number,
part_name,
attenuation_low_end,
attenuation_high_end,
optimum_fermentation_temp_f_low,
optimum_fermentation_temp_f_high
FROM
yeast_module
WHERE
category = 3
AND
(
( `attenuation_low_end` > '31' OR `attenuation_low_end` = '31' )
AND
( `attenuation_high_end` < '40' OR `attenuation_high_end` = '40' )
)
Where I'm trying to get the records with the range of low to high end from 31 and maximum of 40
But it returns me something like this
As you can notice it seems doesn't return the data between 31 to 40
Am I doing this right?
UPDATE
I'm expecting no return since, there's no data between 31-40
You're comparing strings, which performs lexicographic comparisons rather than numeric comparisons. You need to convert to numbers. Adding 0 to a numeric string is a simple way to convert it to a number.
WHERE 0+attenuation_low_end >= 31 AND 0+attenuation_high_end <= 40
If you want ranges contained in the 31-40 range:
where attenuation_low_end >= 31 and attenuation_high_end <= 40
If you want ranges that overlap the 31-40 range:
where attenuation_low_end <= 40 and attenuation_high_end >= 31
If your data is of a string datatype, then you need to convert the values to integers so they can be compared as such.
Containment:
where attenuation_low_end + 0 >= 31 and attenuation_high_end + 0 <= 40
Overlap:
where attenuation_low_end + 0 <= 40 and attenuation_high_end + 0 >= 31

Big-O notation when the function has negative value

i need to proof that 2n^2 - 2n -7 = O(n^2), when the n is 1 or two i got negative value of f(n). i am not sure does the way i proof Big-O is correct.Your help and advice is highly appreciated.
f(n) = 2n^2 - 2n -7 = O(n^2) if c=2;
n=1->2(1)^2 - 2(1) -7 = -7 <= 2*(1)^2
n=2->2(2)^2 - 2(2) -7 = -3 <= 2*(2)^2
n=3->2(3)^2 - 2(3) -7 = 14 <= 2*(3)^2
The definition of Big-Oh has more to do with asymptotic behavior than local behavior. If your function went negative for increasing values of n, say it oscillated, there might be more of a concern. For this function, though, there is no problem: you are free to consider the function for all values greater than some n0 which you alone are allowed to choose. So, if the function going negative early on bothers you, write your proof such that those numbers aren't used. For example:
Base case: for n = 3, f(n) = 2*3*3 - 2*3 - 7 = 18 - 6 - 7 = 5 <= 9 * c = c * 3 * 3 = c * n^2. This is true provided that c >= 5/9.
Induction hypothesis: assume f(n) <= c * n^2 for all n starting at 3 up through k.
Induction step: we must show that f(k+1) <= c * (k+1)^2. We have f(k+1) = 2(k+1)^2 - 2(k+1) - 7 = 2k^2+4k+2 - 2k - 2 - 7 = 2k^2 + 2k - 7 < 2k^2 + 4k < 2k^2 + 4k + 2 = 2(k^2 + 2k + 1) = 2(k+1)^2, so the choice c = 2 works here.
In hindsight, it should be obvious that 2n^2 - 2n - 7 is always less than 2n^2 for positive increasing n.

MySQL Convert From Seconds To Another Custom Format

I have this javascript code that works fine:
function timeup(s) {
var d, h, m, s;
m = Math.floor(s / 60);
s = s % 60;
h = Math.floor(m / 60);
m = m % 60;
d = Math.floor(h / 24);
h = h % 24;
m = m > 9 ? m : "0"+m;
h = h > 9 ? h : "0"+h;
s = s > 9 ? s : "0"+s;
if (d > 0) {
d = d+" days ";
} else {
d = "";
}
return d+h+":"+m+":"+s;
}
SO i need same function but in MySQL(because i do SQL query and don't want to use javascript conversion on client side)
So i need to convert in MySQL seconds to get this same output:
timeup(600000) => 6 days 22:40:00
timeup(60000) => 16:40:00
timeup(6000) => 01:40:00
timeup(600) => 00:10:00
timeup(60) => 00:01:00
timeup(60) => 00:01:00
timeup(6) => 00:00:06
So if seconds below day show HH:MM:SS if seconds greater that day show X days HH:MM:SS
I im trying using CONCAT & TIMESTAMPDIFF but i think maybe it should go if then to compare day below 24h or grater to show custom string X days...any help welcome.
I tested this and it seems to do the job:
DROP FUNCTION IF EXISTS GET_HOUR_MINUTES;
DELIMITER $$
CREATE FUNCTION GET_HOUR_MINUTES(seconds INT)
RETURNS VARCHAR(16)
BEGIN
RETURN CONCAT(LPAD(FLOOR(HOUR(SEC_TO_TIME(seconds)) / 24), 2, 0), ' days ',TIME_FORMAT(SEC_TO_TIME(seconds % (24 * 3600)), '%H:%i:%s'));
END;
$$
DELIMITER ;
Test it like this:
SELECT GET_HOUR_MINUTES(600001);
That returns
'06 days 22:40:01'
It seems to want, at least in MySQL Workbench, to have the database you are using selected before you run it. It saves the function within the database, that is, you can see it in the column on the left with Tables, Views, Stored Procedures and Functions.
I now have another problem with this above function that works only on seconds..but i forget to ask in first question that i have in database stored number:
uptime => 1507977507423
And i need to get seconds and show above format from NOW() time
So for example if i have uptime in database so formula will be: NOW() - uptime, i try using this but i get strange output like 34 days 838:59:59 and that is not correct:
SELECT
CONCAT(LPAD(FLOOR(HOUR(SEC_TO_TIME(UNIX_TIMESTAMP(NOW())-SUBSTRING(uptime, 1, length(uptime) - 2))) / 24), 2, 0), ' days ',TIME_FORMAT(SEC_TO_TIME(UNIX_TIMESTAMP(NOW())-SUBSTRING(uptime, 1, length(uptime) - 2) % (24 * 3600)), '%H:%i:%s')) AS nice_date
FROM streams
WHERE id=1;
I get this:
+-------------------+
| nice_date |
+-------------------+
| 34 days 838:59:59 |
+-------------------+

MySQL - how to compute incremental charges?

Assume a service is billed in the following manner:
The first 60 seconds is charged at $1.00
Subsequent charges are billed at $0.25 per 10 second
The following are example computations:
32 seconds = $1.00
59 seconds = $1.00
60 seconds = $1.00
61 seconds = $1.25
69 seconds = $1.25
70 seconds = $1.25
71 seconds = $1.50
Is it possible to do this kind of computation in MySQL alone?
EDIT 1:
Does something like this work:
SELECT `call_length`,
( 1.00 + ( Round(( `call_length` - 30 ) / 10) * .25 ) ) AS `cost`
FROM `service`
SqlFiddleDemo
CREATE TABLE sec(val INT);
INSERT INTO sec
VALUES (32), (59), (60), (61), (69), (70), (71);
SELECT
val,
1.0 + CASE
WHEN val <= 60.0 THEN 0
WHEN val MOD 10 = 0 THEN 0.25 *((val - 60) DIV 10)
ELSE 0.25 * (((val - 60) DIV 10) + 1)
END AS charge
FROM sec;
EDIT:
Without CASE:
SqlFiddleDemo2
SELECT
call_length,
1.0 + IF( call_length <= 60, 0, 0.25 * CEIL((call_length - 60)/10)) AS cost
FROM service;
This is not much of a MySQL problem, unless the setting in which you need to perform the calculation is somehow difficult(?).
UPDATE ... SET cost_cents = 100 + CEIL(GREATEST(0, duration - 60)/10) * 25;
As a SELECT to match your edit,
SELECT `call_length`,
100 + CEIL(GREATEST(0, `call_length` - 60)/10) * 25 AS `cost`
FROM `service`
Note that this returns cents. For dollars, divide the result by 100...
SELECT `call_length`,
(100 + CEIL(GREATEST(0, `call_length` - 60)/10) * 25) / 100 AS `cost`
FROM `service`

Code Golf: Calculate Orthodox Easter date

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The Challenge
Calculate the Date of the Greek Orthodox Easter (http://www.timeanddate.com/holidays/us/orthodox-easter-day) Sunday in a given Year (1900-2100) using the least amount of characters.
Input is just a year in the form '2010'. It's not relevant where you get it (Input, CommandLineArgs etc.) but it must be dynamic!
Output should be in the form day-month-year (say dd/mm/yyyy or d/m/yyyy)
Restrictions No standard functions, such as Mathematica's EasterSundayGreekOrthodox or PHP's easter_date(), which return the (not applicable gregorian) date automatic must be used!
Examples
2005 returns 1/5/2005
2006 returns 23/4/2006
2007 returns 8/4/2007
2008 returns 27/4/2008
2009 returns 19/4/2009
2010 returns 4/4/2010
2011 returns 24/4/2011
2012 returns 15/4/2012
2013 returns 5/5/2013
2014 returns 20/4/2014
2015 returns 12/4/2015
Code count includes input/output (i.e full program).
Edit:
I mean the Eastern Easter Date.
Reference: http://en.wikipedia.org/wiki/Computus
Python (101 140 132 115 chars)
y=input()
d=(y%19*19+15)%30
e=(y%4*2+y%7*4-d+34)%7+d+127
m=e/31
a=e%31+1+(m>4)
if a>30:a,m=1,5
print a,'/',m,'/',y
This one uses the Meeus Julian algorithm but since this one only works between 1900 and 2099, an implementation using Anonymous Gregorian algorithm is coming right up.
Edit: Now 2005 is properly handled. Thanks to Mark for pointing it out.
Edit 2: Better handling of some years, thanks for all the input!
Edit 3: Should work for all years in range. (Sorry for hijacking it Juan.)
PHP CLI, no easter_date(), 125 characters
Valid for dates from 13 March 1900 to 13 March 2100, now works for Easters that fall in May
Code:
<?=date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));
Invocation:
$ php codegolf.php 2010
$ php codegolf.php 2005
Output:
04/04/2010
01/05/2005
With whitespace:
<?=date("d/m/Y", mktime(0, 0, 0, floor(($b = ($a = (19 * (($y = $argv[1]) % 19) + 15) % 30) + (2 * ($y % 4) + 4 * $y % 7 - $a + 34) % 7 + 114) / 31), ($b % 31) + 14, $y));
This iteration is no longer readable thanks to PHP's handling of assignments. It's almost a functional language!
For completeness, here's the previous, 127 character solution that does not rely on short tags:
Code:
echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));
Invocation:
$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2010
$ php -r 'echo date("d/m/Y",mktime(0,0,0,floor(($b=($a=(19*(($y=$argv[1])%19)+15)%30)+(2*($y%4)+4*$y%7-$a+34)%7+114)/31),($b%31)+14,$y));' 2005
C#, 155 157 182 209 212 characters
class P{static void Main(string[]i){int y=int.Parse(i[0]),c=(y%19*19+15)%30,d=c+(y%4*2+y%7*4-c+34)%7+128;System.Console.Write(d%31+d/155+"/"+d/31+"/"+y);}}
Python 2.3, 97 characters
y=int(input())
c=(y%19*19+15)%30
d=c+(y%4*2+y%7*4-c+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)
This also uses the Meeus Julian algorithm (and should work for dates in May).
removed no longer necessary check for modern years and zero-padding in output
don't expect Easters in March anymore because there are none between 1800-2100
included Python 2.3 version (shortest so far)
Mathematica
<<Calendar`;a=Print[#3,"/",#2,"/",#]&##EasterSundayGreekOrthodox##&
Invoke with
a[2010]
Output
4/4/2010
Me too: I don't see the point in not using built-in functions.
Java - 252 196 190 chars
Update 1: The first algo was for Western Gregorian Easter. Fixed to Eastern Julian Easter now. Saved 56 chars :)
Update 2: Zero padding seem to not be required. Saved 4 chars.
class E{public static void main(String[]a){long y=new Long(a[0]),b=(y%19*19+15)%30,c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),m=c/31;System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);}}
With newlines
class E{
public static void main(String[]a){
long y=new Long(a[0]),
b=(y%19*19+15)%30,
c=b+(y%4*2+y%7*4-b+34)%7+(y>1899&y<2100?128:115),
m=c/31;
System.out.printf("%d/%d/%d",c%31+(m<5?0:1),m,y);
}
}
JavaScript (196 characters)
Using the Meeus Julian algorithm. This implementation assumes that a valid four-digit year was given.
y=~~prompt();d=(19*(y%19)+15)%30;x=d+(2*(y%4)+4*(y%7)-d+34)%7+114;m=~~(x/31);d=x%31+1;if(y>1899&&y<2100){d+=13;if(m==3&&d>31){d-=31;m++}if(m==4&&d>30){d-=30;m++}}alert((d<10?"0"+d:d)+"/0"+m+"/"+y)
Delphi 377 335 317 characters
Single line:
var y,c,n,i,j,m:integer;begin Val(ParamStr(1),y,n);c:=y div 100;n:=y-19*(y div 19);i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;i:=i-30*(i div 30);i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);m:=3+(i-j+40 )div 44;Write(i-j+28-31*(m div 4),'/',m,'/',y)end.
Formatted:
var
y,c,n,i,j,m:integer;
begin
Val(ParamStr(1),y,n);
c:=y div 100;
n:=y-19*(y div 19);
i:=c-c div 4-(c-((c-17)div 25))div 3+19*n+15;
i:=i-30*(i div 30);
i:=i-(i div 28 )*(1-(i div 28)*(29 div(i+1))*((21 -n)div 11));
j:=y+y div 4 +i+2-c+c div 4;j:=j-7*(j div 7);
m:=3+(i-j+40 )div 44;
Write(i-j+28-31*(m div 4),'/',m,'/',y)
end.
Tcl
Eastern Easter
(116 chars)
puts [expr 1+[incr d [expr ([set y $argv]%4*2+$y%7*4-[
set d [expr ($y%19*19+15)%30]]+34)%7+123]]%30]/[expr $d/30]/$y
Uses the Meeus algorithm. Takes the year as a command line argument, produces Eastern easter. Could be a one-liner, but it's slightly more readable when split...
Western Easter
(220 chars before splitting over lines)
interp alias {} tcl::mathfunc::s {} set;puts [expr [incr 3 [expr {
s(2,(s(4,$argv)%100/4*2-s(3,(19*s(0,$4%19)+s(1,$4/100)-$1/4-($1-($1+8)/25+46)
/3)%30)+$1%4*2-$4%4+4)%7)-($0+11*$3+22*$2)/451*7+114}]]%31+1]/[expr $3/31]/$4
Uses the Anonymous algorithm.
COBOL, 1262 chars
WORKING-STORAGE SECTION.
01 V-YEAR PIC S9(04) VALUE 2010.
01 V-DAY PIC S9(02) VALUE ZERO.
01 V-EASTERDAY PIC S9(04) VALUE ZERO.
01 V-CENTURY PIC S9(02) VALUE ZERO.
01 V-GOLDEN PIC S9(04) VALUE ZERO.
01 V-GREGORIAN PIC S9(04) VALUE ZERO.
01 V-CLAVIAN PIC S9(04) VALUE ZERO.
01 V-FACTOR PIC S9(06) VALUE ZERO.
01 V-EPACT PIC S9(06) VALUE ZERO.
PROCEDURE DIVISION
XX-CALCULATE EASTERDAY.
COMPUTE V-CENTURY = (V-YEAR / 100) + 1
COMPUTE V-GOLDEN= FUNCTION MOD(V-YEAR, 19) + 1
COMPUTE V-GREGORIAN = (V-CENTURY * 3) / 4 - 12
COMPUTE V-CLAVIAN
= (V-CENTURY * 8 + 5) / 25 - 5 - V-GREGORIAN
COMPUTE V-FACTOR
= (V-YEAR * 5) / 4 - V-GREGORIAN - 10
COMPUTE V-EPACT
= FUNCTION MOD((V-GOLDEN * 11 + 20 + V-CLAVIAN), 30)
IF V-EPACT = 24
ADD 1 TO V-EPACT
ELSE
IF V-EPACT = 25
IF V-GOLDEN > 11
ADD 1 TO V-EPACT
END-IF
END-IF
END-IF
COMPUTE V-DAY = 44 - V-EPACT
IF V-DAY < 21
ADD 30 TO V-DAY
END-IF
COMPUTE V-DAY
= V-DAY + 7 - (FUNCTION MOD((V-DAY + V-FACTOR), 7))
IF V-DAY <= 31
ADD 300 TO V-DAY GIVING V-EASTERDAY
ELSE
SUBTRACT 31 FROM V-DAY
ADD 400 TO V-DAY GIVING V-EASTERDAY
END-IF
.
XX-EXIT.
EXIT.
Note: Not mine, but I like it
EDIT: I added a char count with spaces but I don't know how spacing works in COBOL so I didn't change anything from original. ~vlad003
UPDATE: I've found where the OP got this code: http://www.tek-tips.com/viewthread.cfm?qid=31746&page=112. I'm just putting this here because the author deserves it. ~vlad003
C, 128 121 98 characters
Back to Meeus' algorithm. Computing the day in Julian, but adjusting for Gregorian (this still seems naive to me, but I cannot find a shorter alternative).
main(y,v){int d=(y%19*19+15)%30;d+=(y%4*2+y%7*4-d+34)%7+128;printf("%d/%d/%d",d%31+d/155,d/31,y);}
I have not found a case where floor(d/31) would actually be needed. Also, to account for dates in May, the m in Meeus' algorithm must be at least 5, therefore the DoM is greater than 154, hence the division.
The year is supplied as the number of program invocation arguments plus one, ie. for 1996 you must provide 1995 arguments. The range of ARG_MAX on modern systems is more than enough for this.
PS. I see Gabe has come to the same implementation in Python 2.3, surpassing me by one character. Aw. :(
PPS. Anybody looking at a tabular method for 1800-2099?
Edit - Shortened Gabe's answer to 88 characters:
y=input()
d=(y%19*19+15)%30
d+=(y%4*2+y%7*4-d+34)%7+128
print"%d/%d/%d"%(d%31+d/155,d/31,y)
BASIC, 973 chars
Sub EasterDate (d, m, y)
Dim FirstDig, Remain19, temp 'intermediate results
Dim tA, tB, tC, tD, tE 'table A to E results
FirstDig = y \ 100 'first 2 digits of year
Remain19 = y Mod 19 'remainder of year / 19
' calculate PFM date
temp = (FirstDig - 15) \ 2 + 202 - 11 * Remain19
Select Case FirstDig
Case 21, 24, 25, 27 To 32, 34, 35, 38
temp = temp - 1
Case 33, 36, 37, 39, 40
temp = temp - 2
End Select
temp = temp Mod 30
tA = temp + 21
If temp = 29 Then tA = tA - 1
If (temp = 28 And Remain19 > 10) Then tA = tA - 1
'find the next Sunday
tB = (tA - 19) Mod 7
tC = (40 - FirstDig) Mod 4
If tC = 3 Then tC = tC + 1
If tC > 1 Then tC = tC + 1
temp = y Mod 100
tD = (temp + temp \ 4) Mod 7
tE = ((20 - tB - tC - tD) Mod 7) + 1
d = tA + tE
'return the date
If d > 31 Then
d = d - 31
m = 4
Else
m = 3
End If
End Sub
Credit: Astronomical Society of South Australia
EDIT: I added a char count but I think many spaces could be removed; I don't know BASIC so I didn't make any changes to the code. ~vlad003
I'm not going to implement it, but I'd like to see one where the code e-mails the Pope, scans any answer that comes back for a date, and returns that.
Admittedly, the calling process may be blocked for a while.
Javascript 125 characters
This will handle years 1900 - 2199. Some of the other implementations cannot handle the year 2100 correctly.
y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y>2099);alert((d+=d<30||++m-34)+"/"+m+"/"+y)
Ungolfed..ish
// get the year to check.
y=prompt();
// do something crazy.
k=(y%19*19+15)%30;
// do some more crazy...
e=(y%4*2+y%7*4-k+34)%7+k+127;
// estimate the month. p.s. The "~~" is like Math.floor
m=~~(e/31);
// e % 31 => get the day
d=e%31;
if(m>4){
d += 1;
}
if(y > 2099){
d += 1;
}
// if d is less than 30 days add 1
if(d<30){
d += 1;
}
// otherwise, change month to May
// and adjusts the days to match up with May.
// e.g., 32nd of April is 2nd of May
else{
m += 1;
d = m - 34 + d;
}
// alert the result!
alert(d + "/" + m + "/" + y);
A fix for dates up to 2399.
I'm sure there is a way to algorithmically calculate dates beyond this but I don't want to figure it out.
y=prompt();k=(y%19*19+15)%30;e=(y%4*2+y%7*4-k+34)%7+k+127;m=~~(e/31);d=e%31+m-4+(y<2200?0:~~((y-2000)/100));alert((d+=d<30||++m-34)+"/"+m+"/"+y)
'VB .Net implementation of:
'http://aa.usno.navy.mil/faq/docs/easter.php
Dim y As Integer = 2010
Dim c, d, i, j, k, l, m, n As Integer
c = y \ 100
n = y - 19 * (y \ 19)
k = (c - 17) \ 25
i = c - c \ 4 - (c - k) \ 3 + 19 * n + 15
i = i - 30 * (i \ 30)
i = i - (i \ 28) * (1 - (i \ 28) * (29 \ (i + 1)) * ((21 - n) \ 11))
j = y + y \ 4 + i + 2 - c + c \ 4
j = j - 7 * (j \ 7)
l = i - j
m = 3 + (l + 40) \ 44
d = l + 28 - 31 * (m \ 4)
Easter = DateSerial(y, m, d)