I have parameter :dateSend which has type timestamp and I am trying to make this evaluation.
CASE WHEN :dateSend <= TO_TIMESTAMP('14:00:00', 'HH24:MI:SS') THEN 0 ELSE 1 END A
It doesn't work. Maybe I should convert :dateSend to time? Like to_char(CAST(:dateSend AS DATE),'hh24:mi:ss') but it doesn't work.
I need to show 0 if time from :dateSend is smaller then 14.00.
It appears that you want to obtain records having a time component which is earlier than 14:00 hours (2pm). If so, then use this:
SELECT
CASE WHEN EXTRACT(hour FROM :dateSend) < 14 THEN 0 ELSE 1 END AS A
FROM yourTable;
Related
I have a Pythonic system that stores student absences data in a SQLite database. Each row includes the start and end time of the absence, represented by the number of seconds since Jan 01 1970. I was asked to add a feature which limits the number of hours of absence per week.
It sounds easy to pull out the amount of hours, using a statement like this:
SELECT (sum(ending-starting)/3600)
FROM requests
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1
The problem is that the limit must only be the hours defined as "mandatory presence." For example, if a user has defined the hours 8:00 to 17:00 as a "mandatory presence," an absence that begins on Sunday at 14:00 and ends on Monday at the same time, will be calculated in the code above 24 hours, while in practice it is only 9 hours.
"Mandatory presence" is defined in the database as two numerical parameters: "morning" and "evening" (always a round hour). Is there a way to make the calculation above taking into account these two numbers?
If it can not be done in sql, I would love to hear how to select the data in sql and then perform the calculation in python.
I believe the following may do what you wish :-
SELECT
(
sum((
(ending - starting)
-(
CASE WHEN starting < strftime('%s',date(starting,'unixepoch')||' 08:00')
THEN strftime('%s',date(starting,'unixepoch')||' 08:00') - starting
ELSE 0
END
+
CASE WHEN ending > strftime('%s',date(starting,'unixepoch')||' 17:00')
THEN ending - strftime('%s',date(starting,'unixepoch')||' 17:00')
ELSE 0
END
)
) /3600)
) AS ha, *
FROM requests
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1
;
MikeT's answer is not entirely working, but it certainly helped me reach the desired result. Here's the perfect statement:
SELECT
(
sum((
(ending - starting)
-(
CASE WHEN starting < strftime('%s',date(starting,'unixepoch')||printf(' %02d:00', morning))
THEN strftime('%s',date(starting,'unixepoch')||printf(' %02d:00', morning)) - starting
ELSE 0
END
+
CASE WHEN ending > strftime('%s',date(ending,'unixepoch')||printf(' %02d:00', evening))
THEN ending - strftime('%s',date(ending,'unixepoch')||printf(' %02d:00', evening))
ELSE 0
END
)
) /3600.0
-(
(24-evening+morning)
*
(round(julianday(ending, 'unixepoch'))-round(julianday(starting, 'unixepoch')))
)
)) AS ha
FROM requests
INNER JOIN students ON requests.student_id = students.ID
INNER JOIN institutes ON students.inst_id = institutes.ID
WHERE student_id = {x}
AND starting BETWEEN {y} AND ({y}+604800)
AND approved = 1;
Thank you very much for your help!
My question is about using case statement in where clause to check for date and assign values to columns. My sample code include.
select * from table
where
column 1 > 10 and
case when column 2 = 1
then
column 3<= 10 and column 4 between (1st day of prev month) and (prev month end) or column 5 = '8888-01-01'
else
column 4 between (1st day of this month) and (yesterday)
end ;
when I am running this code. I am getting 3706 syntax error:expected something in between field and '='.
How to fix this ?
A CASE statement will always return a value or NULL (if none of the conditions matches), so you can use it in your WHERE clause. There are a couple ways to format your CASE statement:
Format 1
CASE
WHEN <condition> THEN <some_expression>
WHEN <another_condition> THEN <another_expression>
ELSE <final_expression>
END
-- Example
CASE
WHEN col1 = 10 THEN 'Y'
WHEN col1 = 20 THEN 'N'
ELSE 'N/A'
END
Format 2
CASE <expression>
WHEN <value> THEN <expression>
WHEN <another_value> THEN <another_expression>
ELSE <final_expression>
END
-- Example
CASE col1
WHEN 10 THEN 'Y'
WHEN 20 THEN 'N'
ELSE 'NA'
END
I'm not sure what you're trying to do with your sample code, but it looks more like pseudo-code and will not work as-is. Your CASE statement is not formatted properly and your column references like column 1 will not work that way. If your column is actually named column 1, then you need to put double-quotes around it:
select * from table where "column 1" > 10
Can you please describe a little more clearly what exactly you are trying to do?
A CASE expression can't be used to create some kind of dynamic conditions. Write it as a bunch of AND/OR conditons:
select * from table
where
column 1 > 10 and
(
( column 2 = 1 and
(column 3<= 10 and column 4 between (1st day of prev month) and (prev month end) or column 5 = '8888-01-01')
)
or
column 4 between (1st day of this month) and (yesterday)
);
Double check the logic, the precedence of logical operators is
parenthesis
NOT
AND
OR
For my AgingCalendar field, I have 3 conditions using CASE WHEN:
CASE WHEN A.[END_DTTM] > A.[STRT_DTTM] THEN C2.[DY_OF_CAL_NUM] - C1.[DY_OF_CAL_NUM]
WHEN A.[END_DTTM] IS NULL and A.[STRT_DTTM] IS NOT NULL THEN C3.[DY_OF_CAL_NUM] - C1.[DY_OF_CAL_NUM]
WHEN A.[END_DTTM] = A.[STRT_DTTM] THEN 1
END AS AgeCalendar
For my third condition, I'm trying to basically say when the End Datetime = Start Datetime, the age in Calendar days should be set to 1 calendar day.
However, in some of the records I'm bringing in, the start date equals the end date, but the times associated with each datetime are different. When this happens, those records are receiving a NULL in the AgeCalendar field.(For example I could have 6/6/2014 0:00:00 = 6/6/2014 0:00:00, and that will give me 1...but if I had 6/6/2014 0:00:00 = 6/6/2014 0:03:59 (or something like that)...it'll give me a NULL value because it's not matching.
How can I update the code above so that I'm basically saying when End Date = Start Date, then 1...regardless of not having matching times?
CASTor CONVERT them as dates to ignore the time.
WHEN CONVERT(DATE, A.[END_DTTM]) = CONVERT(DATE, A.[STRT_DTTM]) THEN 1
OR
WHEN CAST(A.[END_DTTM] AS DATE) = CAST(A.[STRT_DTTM] AS DATE) THEN 1
I would like to find last weeks Friday for example.
Using days as numbers (1 through 7) for example:
1= Monday and so on..
It would be something like this but I'm stuck at the GetLastWeek, Please see below, THANKS.
<%
dim weeknum
weeknum=5
dim GetLastWeek
GetLastWeek=???? <== FIND LAST WEEKS FRIDAY AS A DATE Eg: MM/DD/YYYY
%>
Example: Last weeks Friday was on: <%=GetLastWeek%>
I probably start by working out what is the current day of the week and working back from there, you can use something like this;
Dim today, offsetdays, lastfri
'WeekDay() returns 1 - 7 (Sunday - Saturday).
today = WeekDay(Date())
'Workout the offset then use DateAdd() to minus that number of days.
Select Case today
Case 1 'Sunday
offsetdays = 2
Case 2 'Monday
offsetdays = 3
Case 3 'Tuesday
offsetdays = 4
Case 4 'Wednesday
offsetdays = 5
Case 5 'Thursday
offsetdays = 6
Case 6 'Friday
offsetdays = 7
Case 7 'Saturday
offsetdays = 1
End Select
lastfri = DateAdd("d", -offsetdays, Date())
Bear in mind this is pseudo coded (untested) and could probably be made better by storing the offsets in an array and using that to power the DateAdd() instead.
You can use the Weekday() function to find what day of the week any particular date is. With this you should be able to calculate anything else you like. There is a full reference for the function here:
http://www.w3schools.com/vbscript/func_weekday.asp
Foo.group(:start_at).count(:id)
How I can group this by date ? the "start_at" column is an datetime column
This should work (rails 3):
Foo.order(:start_at).group("DATE(start_at)").count
edit: if you're using PostgreSQL, the query should be
Foo.order("DATE(start_at)").group("DATE(start_at)").count
or you'll get an error
("PGError: ERROR: column "foos.start_at" must appear in the GROUP BY clause or be used in an aggregate function")
Based on
Graphing new users by date in a Rails app using Seer
and
http://www.pastbedti.me/2009/11/grouping-a-timestamp-field-by-date-in-ruby-on-rails-postgresql/
I created a gem for this. https://github.com/ankane/groupdate
Foo.group_by_day(:created_at).count
You can even specify a time zone.
Foo.group_by_day(:created_at, time_zone: "Pacific Time (US & Canada)").count
This is another way to solve this if you manage different time zones. The idea is to add or substract the hours of your timezone:
hours_diff = Time.zone.now.time_zone.utc_offset/(60*60) rescue 0
hours_diff = hours_diff.to_i
date_group = "DATE(form_answers.created_at)"
if hours_diff > 0
date_group = "DATE(DATE_ADD(form_answers.created_at, INTERVAL #{hours_diff} HOUR ))"
elsif hours_diff < 0
date_group = "DATE(DATE_SUB(form_answers.created_at, INTERVAL #{hours_diff.abs} HOUR ))"
end
Foo.group(date_group).count