Getting the totalworkingdays dates through passing the dates dynamically - java

This is my MySQL database table structure and attendancedate datatype is Date:
attendancedate-------admissionnumber------------attendance
2013-10-03-----------LSTM-0008/2013-2014--------present
2013-10-09-----------LSTM-0008/2013-2014--------present
2013-11-02-----------LSTM-0008/2013-2014--------absent
and i want to disaply like that
monthname---------totalworkingdays---------present----absent
october-------------- 2--------------------2----------0
November--------------1--------------------0-----------1
so am writing the below MySQL query:
select monthname(attendencedate) as monthname,
(select distinct count(*)
from lstms_attendence
where attendencedate>='2013-10-03'
and attendencedate<='2013-10-09'
and addmissionno='LSTM-0008/2013-2014')as totalworkingdays,
sum(CASE WHEN attendence = 'present' THEN 1 ELSE 0 END) as present,
SUM(CASE WHEN attendence = 'absent' THEN 1 ELSE 0 END) AS absent
FROM lstms_attendence
WHERE addmissionno='LSTM-0008/2013-2014' GROUP BY monthname(attendencedate);
But the query is display like this:
monthname---------totalworkingdays---------present----absent
November-----------3-----------------------0------------2
October------------3-----------------------2------------1
please give me the exact query and here am passing dates as hardcoded but that dates are passing dynamically through java to that query.
Let me know the how to create dynamically dates and how to pass values to that query.

Try this:
SELECT
MONTHNAME(attendencedate) as the_month,
COUNT(*) as working_days,
SUM(IF(attendance='present',1,0)) as is_present,
SUM(IF(attendance='absent',1,0)) as is_absent
FROM
lstms_attendence
WHERE
addmissionno='LSTM-0008/2013-2014'
GROUP BY
the_month

Your question doesn't make clear what you're asking. What's wrong with your resultset? Is it the presence of your "november" row?
At any rate, you've got an excessively complex query here, as well as one which will break if you happen to include data from multiple years in it.
Instead of using MONTHNAME(attendancedate), we'll use
DATE_FORMAT(attendancedate, '%Y-%c-01') AS attendancemonth
to figure out in which month an attendancedate lies. This simply turns '2013-11-15' into '2013-11-01', the first day of the month in question. In other words, it truncates (rounds down) the date to the first day of the month.
SELECT admissionnumber,
DATE_FORMAT(attendancedate, '%Y-%c-01') AS attendancemonth,
COUNT(*) AS working_days,
SUM(IF(attendance='present',1,0)) AS is_present,
SUM(IF(attendance='absent',1,0)) AS is_absent
FROM lstms_attendence
WHERE attendancedate >= '2013-10-03'
AND attendancedate < '2013-10-06' + INTERVAL 1 DAY
AND admissionnumber='LSTM-0008/2013-2014'
GROUP BY admissionnumber,attendancemonth
Here is a sqlfiddle.http://sqlfiddle.com/#!2/a2dfb/7/0
This summarizes by both admissionnumber and month, so you can produce a report that contains multiple admissions if you want that.
It uses attendancedate < 'last' + INTERVAL 1 DAY in place of attendancedate <= 'last' because that is robust in cases where attendancedate contains a timestamp other than midnight.
If you need to pass in your parameters from Java, use a prepared statement. Replace the constants in the SQL query with ?, and use setTimestamp and setString. For one example, see JDBC Prepared Statement . setDate(....) doesn't save the time, just the date.. How can I save the time as well?

Related

How to use Oracle TRUNC and NVL function together in JPA Predicate?

I have a specific Oracle query that has the following condition in where clause:
SELECT col_a
FROM table_x
WHERE TRUNC(NVL(date_col, sysdate + 365)) >
TRUNC(TO_DATE('11-Jan-2001', 'dd-mon-yyyy'));
I am unable to figure out how to use CriteriaBuilder to create the where clause Predicate. So far, I have figured out a half way but getting stuck at sysdate + 365 part. I specifically need to get DB date as my application current date and DB current date might differ.
Predicate p = criteriaBuilder.greaterThan(
criteriaBuilder.function("TRUNC", LocalDate.class, root.get(date_col)),
criteriaBuilder.function("NVL", LocalDate.class, root.get(date_col))
);
I'm unable to figure out how to get sysdate + 365 and pass it to criteriaBuiler.
Can anyone please help here? I can't post the complete snippet due to corporate restrictions.

MySQL to fetch all the records based on a month of a year

I have a table and in that table there is a column called date_created, which is in TIME STAMP format 2016-07-20 11:30:15 and while I am fetching record I have to pass only the month and year in my front-end field like (month_no/year) 1/2016, 2/2016, 3/2016..... So I have to fetch all the record based upon a month. So how could I achieve this query. So far I tried like this.
SELECT t.*
FROM stock t
WHERE MONTH(str_to_date(t.date_created,'%Y/%M')) = 7
Since you have a timestamp column you don't need to worry too much. You need to put the month number and year number in the corresponding position.
SELECT t.*
FROM stock t
WHERE MONTH(t.date_created) = ?
AND YEAR(t.date_created) = ?;
If month = 7 and year = 2016 then your query:
SELECT t.*
FROM stock t
WHERE MONTH(t.date_created) = 7
AND YEAR(t.date_created) = 2016;
If You have created indexes on columns then i would suggest you not use any function in where clause this makes query slow and non-sargable.. Please use the following link why i am saying this
What makes a SQL statement sargable?
I would Suggest you to use the following query.
SELECT t.*
FROM stock t
WHERE t.date_created between '2016-07-01 00:00:00.000' AND '2016-07-31 00:00:00.000'

Returning records from database between two dates

I've created a program using Java that connects to a database and allows the user to submit a record. This record includes a unique reference number and started date (Variable: StartedDate).
I want to enable the user to search for the amount of cases submitted between two dates (the first day of the month and todays date).
So far I have the SQL query
select * from cases where StartDate>'***' and Date<'****'
In Java, it would be
select * from cases where StartedDate>'1stMONTHDATE' and Date<'TODAYSDATE'
My first question is - Within the database, there isn't a field called "Date" as this would have to change on a daily basis. How would I reference this to be the automatically generated date from Java?
Also, how would I implement the Count() method to return an int of the number of records returned?
SELECT * FROM cases WHERE StartedDate BETWEEN :startDate AND :endDate
In JPQL:
public List<Cases> findAllEvents(Date startDate, Date endDate) {
List<Cases> allCases = entityManager.createQuery("SELECT * FROM cases WHERE StartedDate BETWEEN :startDate AND :endDate")
.setParameter("startDate", startDate, TemporalType.DATE)
.setParameter("endDate", endDate, TemporalType.DATE)
.getResultList();
return allCases ;
}
Well i suppose by "Date" in the query you mean end date.
if that is so you can calculate the end date with either of the two following methods
java using the Calender class and pass the end date as parameter to the query
In the sql by modifying the query like
for ex- here the end date is one month from start date.This is DB specific.This will work in Postgres. Look for the correct syntax according to the DB you use to get the end date
select * from cases where StartedDate>'1stMONTHDATE' and ('StartedDate' + INTERVAL '1 MONTH')<'TODAYSDATE'.
Regarding the count()-A simple SELECT Count(*) will give you the number of rows returned by thw query
If you are using MSSQL and your date values are as String then you can use following query:
SELECT c FROM cases c where CONVERT(VARCHAR(10),StartDate,121) between :startDate AND :endDate
I am using this query in my application with mssql server

Auto Increment including Year and Month in MySql

I have a table called > Project with an auto increment field for project estimate bid number called Project_ID.
This field is auto incremented. I have created it as an 8 digit character field which carries the field rule.
I need it to auto increment as a two number year, two number month, include a hyphen, and then a number starting at 001 for first record in that time period.
An example for the month of April 2012 would be 1204-001 for the first
record, 1204-002 for the 2nd and etc. then when the month of May rolls
around the Project_ID would change to 1205-001.
What I’ve been trying to write is as follows, I kept it as a simple default expression with a default value of
Cyear(date()) + (month()) + “-“ + “001” .
How I have Achieve this?
Basically, you can use BEFORE INSERT TRIGGER on the table you want the column to be incremented.
Here are some steps to create a simple algorithm and put this code inside the trigger:
// get current YEAR
SET #cur_Year = CONCAT(DATE_FORMAT(CURDATE(), '%Y'));
// get current MONTH
SET #cur_MONTH = CONCAT(DATE_FORMAT(CURDATE(), '%m'));
// concatenate YEAR and MONTH
SET #Year_Month = CONCAT(#cur_Year, #cur_MONTH);
// get the last value for the current YEAR and MONTH
SET #max_ID = ( SELECT MAX(ID)
FROM tableName
WHERE ID LIKE CONCAT(#Year_Month, '-%'));
// get the last three characters from the id, convert in to
// integer and increment by 1
SET #last_ID = CAST(RIGHT(#max_ID, 3) AS SIGNED) + 1;
// pad zero on the left using LPAD and
// concatenate it with YEAR and MONTH
SET #new_ID = CONCAT(#Year_Month,'-',LPAD(CAST(#last_ID AS CHAR(3)), 3, '0'));
INSERT INTO (Project_ID, col1, col2, col3)
SELECT DATE_FORMAT(NOW(), CONCAT('%y%m-',
(( SELECT RIGHT(CONCAT('000', (RIGHT(Project_ID, 3) + 1)), 3) AS number
FROM table_name
WHERE LEFT(Project_ID, 5) = DATE_FORMAT(NOW(), '%y%m-'))
ORDER BY Project_ID DESC
UNION
( SELECT '001')
LIMIT 1))),
'Col1 data', 'Col2 data', 'Col3 data'
This might look a bit odd, so I'll just explain the flow:
I use INSERT INTO ... SELECT so that I can check existing data from table_name to see if there are any existing cases already. The WHERE will find existing cases, and thanks to both RIGHT and LEFT it isn't too hard to carve out relevant data needed. If no rows are found, '001' is used instead, then you simply assign the existing columns as shown.
I have absolutely solved it,just take a look..
At first you have to take a sample table where the columns will be same to the columns of your original table except the column project_id.
then first insert a row in the original table where the value of column project_id=0 and the other columns are null,just insert the first row manually like this.
Then create a trigger on the sample table like the following...
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
delimiter ;;
create trigger t after insert on try
for each row
begin
declare v int;
declare c int;
set v=(select max(project_id) from original);
if(v=0)then
insert into original set
project_id=concat((select concat(right(substring_index((select * from(select curdate() from try limit 1) as a),'-','1'),2),right(substring_index((select * from(select curdate() from try limit 1) as a),'-','2'),2)) from try limit 1),'-001'),
project=new.project;
else
set c=(select right((select max(project_id) from original)as x,3) from original limit 1);
insert into original set
project_id=concat((select concat(right(substring_index((select * from(select curdate() from try limit 1) as a),'-','1'),2),right(substring_index((select * from(select curdate() from try limit 1) as a),'-','2'),2)) from try limit 1),concat('-00',c+1)),
project=new.project;
delete from original limit 1;
end if;
end;;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
In the above trigger my sample table was try(project text) and the original table was original(project_id text,project text).
After creating a trigger like this on the sample table,start inserting rows in the sample table,the rows will automatically inserted in the original table with auto_increment values in the project_id column like..1405-001,1405-002,1405-003.... where 14 is 2014 and 05 is May and the rest are auto_incremented values which is being incremented using the trigger.
Just follow the above steps, your problem will be surely solved.

how to find difference between two timestamp using hibernate query language

I am trying to write an hql query which gives me the number of hours between two timestamp.
So, far i am unable to do this. I have used hql hour function but that does not work if the
timestamp corresponds to different date. Please provide any input.
My hql query is
select count(*) from com.xxx.Request as request where request.id = :id and hour(current_timestamp - request.lastEventDate) > :delay
well, you can use:
days(first_timestamp) * 24 + hours(first_timestamp)
- days(second_timestamp) * 24 - hours(second_timestamp);

Categories