Grouping SQL-Result by time does not work - sql

I am trying to set up an SQL query in Firebird 2.5 in order to make a statistic about sales grouped by time.
My approach I followed up so far would be:
SELECT EXTRACT(WEEKDAY FROM ODR.ORDERDATE) AS S1, EXTRACT(HOUR FROM ODR.ORDERDATE) AS S2,
CASE
WHEN (EXTRACT(HOUR FROM ODR.ORDERDATE)) < 10 THEN
'0' || CAST(EXTRACT(HOUR FROM ODR.ORDERDATE) AS VARCHAR(2)) || ':00 - ' || '0' ||
CAST(EXTRACT(HOUR FROM ODR.ORDERDATE) AS VARCHAR(2)) || ':59 '
WHEN EXTRACT(HOUR FROM ODR.ORDERDATE) >= 10 THEN
CAST(EXTRACT(HOUR FROM ODR.ORDERDATE) AS VARCHAR(2)) || ':00 - ' ||
CAST(EXTRACT(HOUR FROM ODR.ORDERDATE) AS VARCHAR(2)) || ':59 '
END AS TINTERVAL,
COUNT(ODR.ID) AS ABSCOUNT
FROM ODR
GROUP BY S1,S2,TINTERVAL
ORDER BY S1,S2 ASC
The syntax of this query seems to be fine for SQL-Connection established by Firebird ODBC 2.5.
My question:
For hour=0 (<10) the query returns a result set which is not presented by the data given by the orders.
e.g. the result-set for this query might look like this:
S1 S2 TINTERVAL ABSCOUNT
0 0 00:00 - 00:59 30
0 1 01:00 - 01:59 2
I don't know how this query comes to its strange count in hour = 0.
This does not make any sense to me.

Related

How to store -00:00 time zone value in snowfkale

I had a scenario in storing the data reading from source file to snowflake table:
Input data line:
3 AC 0060876543NOV221080123 23 5 7 56709000900+0900
I have to read the last four digit in "09:00" format based on the plus or minus symbol. If the data coming as -0900 then in snowflake it should store as "-09:00".
SELECT
(CASE SUBSTR(raw_data, 48, 1)
WHEN '-' THEN CONCAT('-' , SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2))
ELSE CONCAT(SUBSTR(raw_data,49,2) , ':' , SUBSTR(raw_data,51,2)) END) +
(CASE SUBSTR(raw_data,40,4) WHEN '2400' THEN 24 ELSE 0 END)
AS COLUMN_1
FROM
(SELECT temp_row.$1 as raw_data from
#JOB_MANAGEMENT.SNOWFALKE (file_format => 'DB.TBL_FILE_FORMAT',
pattern=>'.*/input_file.txt') temp_table) temp;
But, I'm getting error as below :
For minus value : Numeric value '-04:00' is not recognized
For plus value: Numeric value '09:00' is not recognized
UPDATED:
This is my teradata sql:
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'2400' when '2400' then 24
else 0
end (interval hour));
output : -04:00
select (case '-' when '-' then '-' ||'04' || ':' ||'00'
else '04' || ':' ||'00'
end (Interval hour to minute)) +
(case
'1835' when '2400' then 24
else 0
end (interval hour));
output: 20:00
I want to implement the same in snowflake and thus in the second case statement it is throwing error.
The final column which I need to store the content in varchar column.
SUBSTR(raw_data, LEN(raw_data)-5,3) || ':' || RIGHT(raw_data,2)

Postgresql time as Duration

I need time as duration in postgresql
Eg:- Current time 3/16/2020 13:23:0000
table column entry by 3/15/2020 12:23:0000
so value i need to get is ' 1 day 1 hour ago'
if its like this 3/16/2020 13:20:0000 it should be 3 minutes ago like that
You can do formatting in SQL with something like:
select * from tt;
x
---------------------
2020-02-16 13:30:41
(1 row)
select current_timestamp;
current_timestamp
-------------------------------
2020-03-16 09:38:24.267299+01
(1 row)
select
case when dd > 0 then dd || ' days ' else ' ' end
||
case when hh > 0 then hh || ' hours ' else ' ' end
||
case when mi > 0 then mi || ' minutes ' else ' ' end
||
'ago' as when
from
(
select
extract(day from (current_timestamp - x)) as dd,
extract(hour from (current_timestamp - x)) as hh,
extract(minute from (current_timestamp - x)) as mi
from tt
) as t;
when
--------------------------------
28 days 20 hours 7 minutes ago
(1 row)
You can create a stored function for that:
create or replace function format_timestamp(timestamp) returns text
as
$$
select
case when dd > 0 then dd || ' days ' else ' ' end
||
case when hh > 0 then hh || ' hours ' else ' ' end
||
case when mi > 0 then mi || ' minutes ' else ' ' end
||
'ago' as when
from
(
select
extract(day from (current_timestamp - $1)) as dd,
extract(hour from (current_timestamp - $1)) as hh,
extract(minute from (current_timestamp -$1 )) as mi
) as t;
$$
language sql;

Converting decimals to [h]:mm in sql query

I need a requirement to convert decimal value to time in sql query like if input is 12.5 it should return 12h 30m, if input is 8.70 it should return 8h 42m.
You could use Oracle's numtodsinterval function to achieve this.
select numtodsinterval(to_number('12.5'), 'hour') from dual;
Returns 0 12:30:0.0
select numtodsinterval(to_number('8.70'), 'hour') from dual;
Returns 0 8:42:0.0
Maintain such conversation into a intermediate table and keep mapping to transform
Create a SP to convert and done
If the format literally needs to be like "12h 30m" and "8h 42m", then the following could work:
WITH sample_data AS
(
SELECT NUMTODSINTERVAL(to_number('12.5'), 'HOUR') ds_interval FROM dual UNION ALL
SELECT NUMTODSINTERVAL(to_number('8.70'), 'HOUR') ds_interval FROM dual UNION ALL
SELECT NUMTODSINTERVAL(to_number('122.25'), 'HOUR') ds_interval FROM dual
)
SELECT ( (EXTRACT(DAY FROM sample_data.ds_interval) * 24) +
EXTRACT(HOUR FROM sample_data.ds_interval) ) || 'h ' ||
EXTRACT(MINUTE FROM sample_data.ds_interval) || 'm ' output
FROM sample_data;
OUTPUT
--------
12h 30m
8h 42m
122h 15m
The format could be expanded to convert hours to days when # of hours >= 24:
WITH sample_data AS
(
SELECT NUMTODSINTERVAL(to_number('122.25'), 'HOUR') ds_interval FROM dual
)
SELECT EXTRACT(DAY FROM sample_data.ds_interval) || 'd ' ||
EXTRACT(HOUR FROM sample_data.ds_interval) || 'h ' ||
EXTRACT(MINUTE FROM sample_data.ds_interval) || 'm '
FROM sample_data;
OUTPUT
---------
5d 2h 15m

How to convert Minutes to Hours Minutes and Seconds in SQL?

Currently I am using this query, which gives me duration in minutes.
Part of My query
Select
E.xyme
From
(SELECT Timee as xyme from
(select round(avg(tableT.DURATIONMIN),2) as Timee
FROM ownerName.tableT tableT
where tableT.FLAG = 0 )
)E
Output would be
Xyme
----
125.58
Output Looking for
Xyme
----
2 hours, 5 minutes, 35 seconds
Part solution
I know we can use something like below but I am not able to implement.
floor((sysdate-Timee)*24)
|| ' HOURS ' ||
mod(floor((sysdate-Timee)*24*60),60)
|| ' MINUTES ' ||
mod(floor((sysdate-Timee)*24*60*60),60)
|| ' SECS ' Duration
You can convert the numeric value for the minutes to an interval type using the numtodsinterval() function, and then extract() the elements from that:
select extract (hour from numtodsinterval(timee, 'MINUTE')) || ' hours, '
|| extract (minute from numtodsinterval(timee, 'MINUTE')) || ' minutes, '
|| extract (second from numtodsinterval(timee, 'MINUTE')) || ' seconds' as xyme
from (select 125.58 as timee from dual);
XYME
----------------------------------------
2 hours, 5 minutes, 34.8 seconds
You can round or trunc the seconds value as appropriate; looks like you want round from your sample.

DB2 date conversion

I have 2 INTEGER columns like the following:
Month Year
----- -----
5 2011
Is there any way to convert that to a single column VARCHAR like this: May-2011
I don't know of an easy way to do this since you don't have a date object (ie its not like youre finding the month of a timestamp), you can use a case statement but it gets long.
SELECT CASE Month
WHEN '1' THEN 'January'
WHEN '2' THEN 'February'
WHEN '3' THEN 'March'
WHEN '4' THEN 'April'
...
END+'-'+Year
FROM TABLE
I think this will do it:
SELECT
MONTHNAME(
DATE(CAST(Year AS CHAR(4)) || '-' || TRIM(CAST(Month AS CHAR(2))) || '-1')
) || '-' || CAST(Year AS CHAR(4))
FROM TABLE
This should do the trick, assuming that the columns Month and Year are integers and Month has the domain 1-12:
select substring('---JanFebMarAprMayJunJulAugSepOctNovDec', 3*Month , 3 )
+ '-'
+ right(digits(Year),4)
from some_table
If Month is 0 you'll get '---' as the month; if it's less than 0 or greater than 12, you'll get some sort of blooey.
You could create a function to convert the month value, like this...
CREATE FUNCTION INT2MONTH (MONTH INTEGER)
RETURNS VARCHAR(100)
LANGUAGE SQL
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
RETURN MONTHNAME('2000-' || RIGHT('0' || STRIP(CHAR(MONTH)), 2) || '-01')
Then you can...
select int2month(month) || '-' || strip(char(year)) from test
1
--------------------------------------------------
May-2011
June-2011
December-2012
If you want a 3 char month then change last last on function to...
RETURN LEFT(MONTHNAME('2000-' || RIGHT('0' || STRIP(CHAR(MONTH)), 2) || '-01'), 3)
I realize this question is pretty old, but there's a way that is a lot simpler than any of the options listed here (in my opinion) -- a combination of some date math and the VARCHAR_FORMAR() function:
SELECT
VARCHAR_FORMAT(
DATE('0001-01-01') + (month_col - 1) MONTH + (year_col - 1) YEAR
,'Month-YYYY'
)
FROM your_table