select records between two months with year difference - mysql

I have a table which contain records of people according to month and year.
table have multiple columns in which there are two columns which are fldmonth & fldyear, which contain month no and year respectively.
Now I want to fetch data between months of different year. (E.g. 3-2012 to 6-2013)
I am using following query, but not getting proper record.
SELECT * FROM 'table' WHERE
user_id = 'id' AND
STR_TO_DATE(CONCAT('fldyear', 'fldmonth', '01'), '%Y%m%d') BETWEEN
STR_TO_DATE(CONCAT('2012', '3', '01'), '%Y%m%d') AND
STR_TO_DATE(CONCAT('2013', '6','01'), '%Y%m%d');
Table Schema :
user_id varchar(100), fldmonth smallint(2), fldyear mediumint(4)
(table name & userid given here are just for example)
Please need help.
Note: I used %c also in date format because month are in 1,2,..12 format. But still am getting empty result set

SELECT * FROM tbl
WHERE USERID=1 and
STR_TO_DATE(CONCAT(fldyear,'-',LPAD(fldmonth,2,'00'),'-',LPAD(fldate,2,'00')), '%Y-%m-%d')
BETWEEN
STR_TO_DATE(CONCAT(2012,'-',LPAD(03,2,'00'),'-',LPAD(01,2,'00')), '%Y-%m-%d') AND
STR_TO_DATE(CONCAT(2013,'-',LPAD(06,2,'00'),'-',LPAD(01,2,'00')), '%Y-%m-%d');
Working Fiddle

Remove Single quote from column names.
Try this:
SELECT *
FROM table
WHERE user_id = 'id' AND
STR_TO_DATE(CONCAT(fldyear, fldmonth, '01'), '%Y%c%d') BETWEEN '2012-03-01' AND '2013-06-01';

Saharsh Shah is right, but what you need is to add brackets () too in your condition
change the condition with
WHERE user_id = 'id' AND
( STR_TO_DATE(CONCAT(fldyear, fldmonth, '01'), '%Y%m%d')
BETWEEN '2012-03-01' AND '2013-06-30' );

Related

MYSQL table search-filtering

I have a table student with a column dte_date (date) having values (2019-01-01,2019-02-01,2019-03-01..etc)
Conditions:
No repeated values in the column dte_date.
But there is a chance of missing values in dte_date(example miss 2019-02-01).
The day of the date field should be 01.
I want a query to check whether any month date is missing from this table.
You can use aggregating and having:
select student_id
from t
group by student_id
having max(dte_date) <> min(dte_date) + interval count(*) - 1 month;
Note that this assumes that you don't have duplicates in the table -- although that could be handled with count(distinct).

Get the running total of a column filtered by month and year

I have a MySQL database table called user_inputs with userId(str), year(int), month(int) and input(int) columns.
I need to get the last 12 months of record per user, and get the sum of the input column.
So far I came up with the following:
CREATE TEMPORARY TABLE temp
AS (SELECT *, CAST(CONCAT(`year`, '-', `month`, '-01' ) AS DATE) AS `NewDate` FROM `user_inputs`);
SELECT `userId`, SUM(`input`) AS `running_total` FROM temp
WHERE `userId` = 266
AND `NewDate` BETWEEN STR_TO_DATE(CONCAT('2018', '01', '01'), '%Y%m%d')
AND LAST_DAY(STR_TO_DATE(CONCAT('2018', '12', '01'), '%Y%m%d'));
Is there a way this two statements could be simplified and combined into one, without having to create a temporary table? The goal is to be able to filter the results using a beginning month/year and ending month/year combinations and get the sum of inputs from the result.
Note: I've decided to just add a generated column that combines the month and year columns.

SQL - Performing a query on a result from another query?

I have a column(varchar) with date values, I need to find those dates which are expiring in next 30 days.
ExpiringDate
===================
20171208,
20171215,samples
20171130,tested
N/A
No
(empty row)
So, First I need to get values before comma. On the resultset, I need to filter out rows that has only numbers(no 'N/A' or 'No' or empty rows) & then I need to filter those dates which are expiring in next 30 days.
Edited
I have tried the following & resultset seems to be inappropriate
SELECT
DocName,
CategoryName,
AttributeName,
CAST(SUBSTRING_INDEX(AttributeValue, ',', 1) AS DATE) AS ExpiredDate
FROM myDB
WHERE (AttributeName = 'Date of last vessel OVID' OR AttributeName = 'Next Statutory docking' OR
AttributeName = 'Last statutory docking') AND AttributeValue LIKE '%[^0-9]%' AND
DATEDIFF(now(), AttributeValue) <= 30;
Because you are not only storing dates as text, but mixing those dates with entirely non date information, this complicates things. In this case, we can do two checks, one to ensure that the record starts with an actual expected date, and the second to make sure that the date diff is within 30 days from now.
SELECT ExpiringDate
FROM
(
SELECT ExpiringDate
FROM yourTable
WHERE ExpiringDate REGEXP '^[0-9]{8}'
) t
WHERE
DATEDIFF(LEFT(ExpiringDate, 8), NOW()) BETWEEN 0 AND 30;
Note that I use a subquery to first remove rows that do not even have a parseable date. The reason for this is that DATEDIFF will error out if not passed valid dates for both parameters.
Demo

Insert / Select in mySQL

I want to select all pat_id and its pat_date_hired in the patient table, and then insert it in the appointment table.
pat_id is the same value as pat_id in the appointment table, and pat_date_hired will be the value of app_date, but the year must be changed to the current year.
For example: If pat_date_hired = 10-26-2014, then app_date must be 10-26-2016.
Here is the idea:
insert into appointment (pat_id, app_date, app_type)
values
(*select the pat_id and pat_date_hired and change the year to current year*, "PE")
I'm new to MySQL. I have very limited knowledge. Any help will be appreciated.
try using DATE_FORMAT to change the year
example as below
insert into appoinment (pat_id, app_date, app_type) value(
SELECT pat_id FROM patient_table where pat_id = appointment_table.pat_id
,
DATE_FORMAT(SELECT pat_date_hired FROM patient_table where pat_id = appointment_table_pat_id, YEAR(current_DATE)+'/%m/%d'))
This is the logic I would use in SQL Server (you would need to find the replace for the logic of generating app_date. Similar thing should be available in MySql):
INSERT INTO appointment (pat_id, app_date, app_type)
SELECT
pat_id
,DATEADD(yy, YEAR(GETDATE()) - YEAR(pat_date_hired), pat_date)
, <value for app_type or app_type column>
FROM patient_table
In first place, I would give you advice on the date format you are using; month-day-year won´t be recognized by mysql; you would be better using Y-m-d
Said that; 1st step, use STR_TO_DATE(date_string, format) to convert your date to a valid mysql date; 2nd step, use YEAR(NOW()) to get current year; 3rd step: concat them. Your query would look like the following:
insert into appointment (pat_id, app_date, app_type)
select pat_id,
CONCAT(
YEAR(NOW()),
"-",
DATE_FORMAT(STR_TO_DATE("10-26-2016","%m-%d-%Y"), "%m-%d")
),
"PE")
Note that, I made the query so it would return "Y-m-d" date format, if you wanted it to be "m-d-Y" change this
CONCAT(
YEAR(NOW()),
"-",
DATE_FORMAT(STR_TO_DATE("10-26-2016","%m-%d-%Y"), "%m-%d")
)
to this
CONCAT(
DATE_FORMAT(STR_TO_DATE("10-26-2016","%m-%d-%Y"), "%m-%d"),
"-",
YEAR(NOW()),
)

mysql select with priority of 3 filelds in a query

my table and fields are like these:
i must find $sy<year<$ey then it must filter only values by $sm<month<$em at last it must find $sd<day<$ed
i need to find records between dates for example like 2010/10/25 , 2010/10/10
at first i tried :
SELECT SUM(barname) allin,SUM(rooz) allhoghogh,user_id FROM work_result
WHERE (`year`>='$sy' and `month`>='$sm' and `day`>='$sd') and (`year`<='$ey' and `month`<='$em' and `day`<='$ed') group by user_id ;
but it cant find records for dates like e like 2010/10/25 , 2010/10/28
than i tried
SELECT * FROM work_result as t1 join work_result as t2 on t1.year<='$sy' and t2.year>='$ey' and t1.month<='$em' and t2.month>='$sm' and t1.day<='$ed' and t2.day>='$sd' WHERE 1 group by t1.wrid
this isnt usful in my case!
i need some thing like priority select first select all between years than month and than day!!
other way is convert mysql records to timestamp by year and month and day and compare it by input date but UNIX_TIMESTAMP('year-month-day 00:00:00') dont worked correct for me.
i used it like :
SELECT * FROM `work_result` WHERE UNIX_TIMESTAMP('year-month-day 00:00:00')>1238921453
If convert to timestamp didn't work for you what about use date_format to convert:
SELECT *
FROM `work_result`
WHERE date_format(concat(year,'-',month,'-',day), '%Y-%m-%d') >
DATE_FORMAT(FROM_UNIXTIME(`yourDateGoesHere`), '%Y-%m-%d')