MS Access - Data type mismatch - simple integer comparison - ms-access

I just cannot wrap my head around why I am getting this error?
"Data type mismatch in criteria expression."
SELECT * INTO Updated FROM (
SELECT a.*,
date() AS [Today],
DateValue([Last_Updated]) as [LastUpDateDate],
int(datediff("d", date(), DateValue([Last_Updated]))) as [mydatediff]
FROM Prior AS a
WHERE a.[Last_Updated] is not null
) t
WHERE t.[mydatediff] >= 1;
I just want a simple comparison of two integers and I keep getting the type mismatch error.

If Last_Updated is text, it probably holds some invalid date expressions.
Try using IsDate to filter those out:
SELECT * INTO Updated
FROM
( SELECT
a.*,
Date() AS [Today],
DateValue([Last_Updated]) AS [LastUpDateDate],
DateDiff("d", Date(), DateValue([Last_Updated])) AS [mydatediff]
FROM
Prior AS a
WHERE
IsDate(a.[Last_Updated])
) t
WHERE
t.[mydatediff] >= 1;
Alternatively, filter the subquery:
SELECT
t.*,
Date() AS [Today],
DateValue(t.[Last_Updated]) AS [LastUpDateDate],
DateDiff("d", Date(), DateValue(t.[Last_Updated])) AS [mydatediff]
INTO
Updated
FROM
( SELECT *
FROM Prior
WHERE IsDate([Last_Updated])
) t
WHERE
DateDiff("d", Date(), DateValue(t.[Last_Updated])) >= 1;
Solution
The trick is to force the subquery to finalise before retrieving its records. That can be done with DISTINCT:
SELECT *
FROM (
SELECT DISTINCT
Prior.Id,
DateValue([Last_Updated]) AS LastUpDateDate,
DateDiff("d",Date(),DateValue([Last_Updated])) AS mydatediff
FROM
[Prior]
WHERE
IsDate([Last_Updated]) <> False
) AS T
WHERE T.mydatediff >= 1;
Sample:
Output:

Related

Validating age using a function in MySQL

so i'm having some issues using a function in SQL where i calculate the age given a certain date. The thing is that i need to validate with the current date and the date of birth if it's already the year or not.
For example the date i have in a register is 1994-11-15 and when consulting the information with
select EmployeeID Num_Emloyee, concat(FirstName, " . ", LastName) Name_Employee, Title Puesto, fn_Age(BirthDate) Edad, fn_Age(HireDate) WorkYears
from employees;
It returns 24, however if i only consult with select the function it returns 23, the correct answer.
At the moment this is the function i'm using to validate the age is this:
create function fn_Age(dateVal date)
returns int
begin
declare age int;
if day(now()) and month(now()) >= day(dateVal) and month(dateVal) then
set age=year(now())-year(dateVal);
else
set age=(year(now())-year(dateVal)) - 1;
end if;
return age;
end
Is there anything i'm not considering in the function?
day(now()) and month(now()) >= day(dateVal) and month(dateVal)
This logic doesn't make sense. I don't know if an if supports tuples in MySQL. If so, you can do:
(month(now()), date(now())) >= ( month(dateval), day(dateval) )
(this works in a MySQL WHERE clause.)
You can also do:
month(now()) * 100 date(now()) >= month(dateval) * 100 + day(dateval)
You can also use timestampdiff-function
select timestampdiff(year, '1994-11-15', now());

OpenQuery Date Selection

I have the below openquery which works fine but now I want to select only transactions >= '2017-07-01' using gl_trans.gl_trans_date but cannot get the correct syntax. The backend database is Informix
I have tried many suggestions via google without success :(
SELECT *
FROM OpenQuery(PRONTO_L01, 'SELECT
gl_trans.gl_accountcode,
gl_trans.gl_amount,
gl_trans.gl_trans_date ,
gl_trans.gl_details
FROM gl_trans
WHERE gl_trans.gl_amount <> 0')
Modify query on WHERE clause & add new column condition with it as shown below. Try this:
SELECT *
FROM OpenQuery(PRONTO_L01, "SELECT
gl_trans.gl_accountcode,
gl_trans.gl_amount,
gl_trans.gl_trans_date ,
gl_trans.gl_details
FROM gl_trans
WHERE gl_trans.gl_amount <> 0 AND gl_trans.gl_trans_date >= '2017-07-01'")
Problem was with Informix date format being MM-DD-2017, resolved using DATE function as below
gl_trans.gl_trans_date >= DATE('07-01-2017)'"
I did something like that and it worked.
Declare #date DATETIME = '2017-07-01';
SELECT *
FROM OpenQuery(PRONTO_L01, 'SELECT
gl_trans.gl_accountcode,
gl_trans.gl_amount,
gl_trans.gl_trans_date ,
gl_trans.gl_details
FROM gl_trans
WHERE gl_trans.gl_trans_date >= ''''' +
CONVERT(CHAR(19), #date, 120) + N'''''''))

Mysql and between\in range condition

We have x2 columns min and max. Each can be null or integer. When we start search throw table we cannot use BETWEEN command... Question is, how to find in range with this conditions
value is greater then min (if it's not null)
and
value is less then max (if it's not null)
and
value is in range of min and max (if they BOTH not null)
value - our integer number. As you can see we cannot use BETWEEN command.
So NULL means no limit. You can still use BETWEEN:
select *
from mytable
where #value between coalesce(minvalue, #value) and coalesce(maxvalue, #value);
Or simply AND:
select *
from mytable
where #value >= coalesce(minvalue, #value)
and #value <= coalesce(maxvalue, #value);
Or the very basic AND and OR:
select *
from mytable
where (#value >= minvalue or minvalue is null)
and (#value <= maxvalue or maxvalue is null);
Use this:
WHERE col BETWEEN COALESCE(min, -2147483648) AND COALESCE(max, 2147483647)
According to your logic, if either the min or max be NULL, then the restriction should be ignored. In the above WHERE clause, if min be NULL then col will always be greater than the lower boundary, assuming that col is an integer. Similar logic applies to the max condition.
The large (and small) numbers you see represent the largest and smallest possible values for an integer in MySQL.
Without the option of using BETWEEN, I would recommend using a simple WHERE-AND clause.
If null values are not allowed, you should use the COALESCE function
http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce
Returns the first non-NULL value in the list, or NULL if there are no non-NULL values.
SELECT *
FROM SCORES
WHERE score >= COALESCE(min_score, score)
AND score <= COALESCE(max_score, score)
Here is a sample fiddle I created
http://sqlfiddle.com/#!9/306947/2/0
My solution Yii2 AR like
$query
->joinWith(['vacancySalary'])
->andWhere([
'and',
'IF (vacancy_salary.min IS NULL, ' . $this->salaryMin . ', vacancy_salary.min) >= ' . $this->salaryMin,
'IF (vacancy_salary.max IS NULL, ' . $this->salaryMin . ', vacancy_salary.max) <= ' . $this->salaryMin
]);
Simple answer is use IF condition and proper values.
ADDED:
Another way to go
$query
->joinWith(['vacancySalary'])
->andWhere($this->salaryMin . ' BETWEEN IF(vacancy_salary.min IS NULL, 0, vacancy_salary.min) AND IF(vacancy_salary.max IS NULL, 0, vacancy_salary.max)');

Error in plpgsql function: array value must start with "{" or dimension information

I'm trying to format the results of this query:
CREATE OR REPLACE FUNCTION "alarmEventList"(sampleid integer
, starttime timestamp without time zone
, stoptime timestamp without time zone)
RETURNS text[] AS
$BODY$DECLARE
result text[];
BEGIN
select into result array_agg(res::text)
from (
select to_char("Timestamp", 'YYYY-MM-DD HH24:MI:SS')
,"AlertLevel"
,"Timestamp" - lag("Timestamp") over (order by "Timestamp")
from "Judgements"
WHERE "SampleID" = sampleid
and "Timestamp" >= starttime
and "Timestamp" <= stoptime
) res
where "AlertLevel" > 0;
select into result array_to_string(result,',');
return result;
END
$BODY$
LANGUAGE plpgsql VOLATILE
Right now without array_to_string() I get something like this:
{"(\"2013-10-16 15:10:40\",1,00:00:00)","(\"2013-10-16 15:11:52\",1,00:00:48)"}
and I want something like this:
2013-10-16 15:10:40,1,00:00:00 | 2013-10-16 15:11:52,1,00:00:48 |
But when I run the query I get error:
array value must start with "{" or dimension information
You do not actually want an array type, but a string representation.
Can be achieved like this:
CREATE OR REPLACE FUNCTION "alarmEventList"(sampleid integer
, starttime timestamp
, stoptime timestamp
, OUT result text) AS
$func$
BEGIN
SELECT INTO result string_agg(concat_ws(','
,to_char("Timestamp", 'YYYY-MM-DD HH24:MI:SS')
,"AlertLevel"
,"Timestamp" - ts_lag)
, ' | ')
FROM (
SELECT "Timestamp"
,"AlertLevel"
,lag("Timestamp") OVER (ORDER BY "Timestamp") AS ts_lag
FROM "Judgements"
WHERE "SampleID" = sampleid
AND "Timestamp" >= starttime
AND "Timestamp" <= stoptime
) res
WHERE "AlertLevel" > 0;
END
$func$ LANGUAGE plpgsql
The manual on string_agg() and concat_ws().

Hundred year date conversion in ssis derived column

I'm trying to convert a Hundred Year Date (HYD) format to a regular date format through SSIS derived column transform. For example: Convert 41429
to 06/04/2013. I can do it with formatinng code within a script (and maybe I simply have to go this route) but feel there has to be a way to do so within a derived column that I'm just not getting. Any help is appreciated.
This is what I came up with. Are you sure your conversion is correct? My answer is 1 day. off.
DECLARE #t1 as date = '01/01/1900';
DECLARE #t2 as DATE = '12/31/1900';
DECLARE #hyd as INT;
-- This example shows that we need to add 1
SELECT #hyd = DATEDIFF (d, #t1, #t2) + 1 -- 364 + 1
SELECT #hyd
set #t2 = '06/04/2013';
SELECT #hyd = DATEDIFF (d,#t1, '06/04/2013') + 1-- 41427
SELECT #hyd
SELECT DATEADD (d, #hyd, '01-JAN-1900')
SELECT DATEADD (d, 41429, '01-JAN-1900')
A hundred year date is a calculation based on the number of days since 1899-12-31. It's an "Excel Thing". It also has a bug in it that you must account for.
The equivalent TSQL logic would be
DECLARE
#HYD int = 41429;
SELECT
#HYD =
CASE
WHEN #HYD > 60
THEN #HYD -1
ELSE
#HYD
END;
SELECT
DATEADD(d, #HYD, '1899-12-31') AS HYD;
Armed with that formula, I can write the following Expression in a Derived Column Transformation (assuming you have a column named HYD)
(HYD > 60) ? DATEADD("d",HYD - 1,(DT_DATE)"1899-12-31") : DATEADD("d",HYD,(DT_DATE)"1899-12-31")
And the results
--or inline SQL...using this
SELECT
case when ([HYD] > 60) then
DATEADD(day,[HYD] - 1,'1899-12-31')
else
DATEADD(day,[HYD],'1899-12-31')
end 'HYD_conv'
FROM
TableName
--and in the where clause if you like...
WHERE
(case when ([HYD] > 60) then DATEADD(day,[HYD] - 1,'1899-12-31') else DATEADD(day,[HYD],'1899-12-31') end) = '2016-01-14'