Using the CASE function in MYSQL with Zend_DB_Expr - zend-framework

I'm stuck with the following problem. In my product table i've two columns
Date_start and Date_end (both of them are a DATE datatype in my table).
I want to check if the current date is between the Date_start and Date_end then the status must be 'not available', else it must have the status 'available'.
How can I fix that in Zend_Db_Expr?
I've now the following query.
$getProducts = $this->oSelect
->from(array('p'=>'producten'))
->columns(array('link' => "CONCAT('/t/', p.titel_key)"))
->joinLeft(array('c'=>'categorie'),'p.categorie_id = c.id',array('cat_titel'=>'c.titel'))
->joinLeft(array('sc'=>'subcategorie'),'p.subcategorie_id = sc.id', array('subcat_titel'=>'sc.titel'))
->where('p.online = 1');

In your columns:
->columns(array('link' => "CONCAT('/t/', p.titel_key)",
'status' => new Zend_Db_Expr("...")))
The 'CASE' should look something like this (i split it out for readability);
CASE WHEN p.Date_end < NOW() AND p.Date_start > NOW()
THEN 'not available' ELSE 'available' END
Zend_Db_Expr will take anything you give it and use it literally. Just remember that any DB specific commands might break if for some reason you switch systems.

Related

case when in where clause postresql

select service_code,service_cat_code,mobile_no,upper(applicant_name_eng) as name,to_char(license_date,'dd/mm/yyyy')as license_from,to_char(license_valid_upto,'dd/mm/yyyy')as license_to,Upper(license_no),district_code,taluk_code,CONCAT(address_building,', ', address_cityvillage,', ',address_locality,', ',address_landmark,', ',address_street) as address
from mst_license
WHERE cast(license_valid_upto as date) = case
WHEN license_valid_upto < now()
THEN
case
when license_valid_upto = '2021-06-30'
then 1 else 0
END
ELSE
case when license_valid_upto > now()
then 1 else 0
End
END
and Upper(license_no)='1SP146924BJP'
I want license valid should be either greater than now or if license valid less than now it must be with the date ''30/06/2021' but when i use above query i get error
ERROR: operator does not exist: date = integer
LINE 3: WHERE cast(license_valid_upto as date) = case
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 418
Help me out guys
The main issue you have is that your case statement returns an integer (1 or 0) but you are trying to compare that to a date, which you cannot do as Postgres is a strict data typing. Even if it did work it would always be false (well except for 1969-12-31/1970-01-01). Moreover the case structure is not needed. The best/correct to compare dates is just use date values. Since you did not indicate the data type for column license_valid_upto so based on how it is used I'll assume it is timestamp with timezone as that is what NOW() returns. Your query becomes:
select service_code
, service_cat_code
, mobile_no
, upper(applicant_name_eng) as name
, to_char(license_date,'dd/mm/yyyy')as license_from
, to_char(license_valid_upto,'dd/mm/yyyy')as license_to
, upper(license_no) as license_no
, district_code
, taluk_code
, concat(address_building,', '
,address_cityvillage,', '
,address_locality,', '
,address_landmark,', '
,address_street) as address
from mst_license
where and upper(license_no)='1SP146924BJP'
and ( cast(license_valid_upto as date) > cast( now() as date)
or (cast (icense_valid_upto as date) < cast( now() as date)
and cast (icense_valid_upto as date) = date '2021-06-30'
)
);
Also, learn for format your queries for readability and so you do not need to scroll right. You, and others looking at your queries later will appreciate it later.

Oracle dbms_scheduler error with BYTIME

I was trying to get a job run every business day (MON to SAT) at 6:30am which the Oracle scheduler refused with
ORA-27419 "unable to determine valid execution date from repeat
interval"
I started losing my mind when i discovered the following behaviour:
First, create a dummy job. Note that it has no schedule and is not enabled.
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => '"TMP_DUMMY"',
job_type => 'PLSQL_BLOCK',
job_action => 'begin
dbms_lock.sleep(5);
end;',
number_of_arguments => 0,
start_date => NULL,
end_date => NULL,
enabled => FALSE,
auto_drop => FALSE,
comments => 'Test Job');
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => '"TMP_DUMMY"', attribute => 'store_output', value => TRUE);
DBMS_SCHEDULER.SET_ATTRIBUTE( name => '"TMP_DUMMY"', attribute => 'logging_level', value => DBMS_SCHEDULER.LOGGING_OFF);
END;
/
Next step, set a repeat_interval using BYTIME with any execution time which is equal to or less than 02:55 (MI:SS) after the full hour. It does not matter whether this is done with or without the Hour part and for the former option the exact hour does not matter as well.
BEGIN
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYTIME=010255');
DBMS_SCHEDULER.enable(name=>'"TMP_DUMMY"');
END;
/
This works perfectly fine for me.
Now i want to increase the BYTIME by 1 second to 02:56 (MI:SS)
BEGIN
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYTIME=010256');
END;
/
Running this attribute change i get
ORA-27470: failed to re-enable "[schema]"."TMP_DUMMY" after making requested change
ORA-27419: unable to determined valid execution date from repeat interval
I have verified this behaviour for all MI:SS combinations:
set serveroutput on
DECLARE
l_rep_interval VARCHAR2(50 CHAR);
BEGIN
FOR mi IN 0..59
LOOP
FOR ss IN 0..59
LOOP
l_rep_interval := 'FREQ=DAILY;BYTIME='||lpad(to_char(mi*100+ss),4,'0');
DBMS_SCHEDULER.set_attribute( name => '"TMP_DUMMY"', attribute => 'repeat_interval', value => l_rep_interval);
DBMS_SCHEDULER.enable(name=>'"TMP_DUMMY"');
DBMS_OUTPUT.PUT_LINE(l_rep_interval);
END LOOP; --end ss
END LOOP; --end mi
EXCEPTION WHEN OTHERS THEN NULL;
END;
/
It is working properly from 00:00 until 02:55 and fails for all other times.
For me this looks like the MI:SS part is treated as a tinyint and higher values cause a type overflow.
Is this a Bug in the scheduler or am i missing something here?
Oracle version is 12c.
I just ran into this same issue. It looks like (from the documentation) that BYTIME is not recognised (even though SQLDeveloper uses it if you look at the SQL tab of the job GUI)
I found that the following works using BYMinute and ByHour
DBMS_SCHEDULER.set_attribute( name => '"TEST"."JOB"', attribute => 'repeat_interval', value => 'FREQ=DAILY;BYHOUR=9;BYMINUTE=30;BYDAY=MON,TUE,WED,THU,FRI,SAT,SUN');
Hope this helps someone.

how to add date in Teradata?

Hi i want to add 01/01/1970 to a column ,datatype of last_hit_time_gmt is bigint ,when i run the below query i am getting data type
last_hit_gmmt
does not match a defined datatype name.
select
distinct STG.OMN_APND_KEY,
STG.last_hit_time_gmt,
IIF(STG.last_hit_time_gmt <>0,ADD_TO_DATE(TO_DATE('01/01/1970', 'DD/MM/YYYY'),'SS',cast(STG.last_hit_time_gmt as DATE ),NULL)
from EDW_STAGE_CDM_SRC.STG_OMNITUREDATA STG
WHERE
UPPER(STG_OMNITUREDATA.EVAR41) IN
('CONS_SUPP: CONSUMER','STORE','PURCHASE') and
STG.OMN_APND_KEY='61855975'
please help me..
The query and data type is incompatible with Teradata.
As stated in the comments you may want to use "CASE" instead of "IFF". The general format is
CASE WHEN *condition* THEN *result_if_true*
ELSE *result_if_false*
END as *ColumnName*
editing based on comment response
So in your query example the case statement can be used like...
select distinct STG.OMN_APND_KEY
,STG.last_hit_time_gmt
,CASE WHEN STG.last_hit_time_gmt = 0 THEN NULL
ELSE DATE '1970-01-01'
END AS YourColName
FROM EDW_STAGE_CDM_SRC.STG_OMNITUREDATA STG
WHERE UPPER(STG_OMNITUREDATA.EVAR41) IN
('CONS_SUPP: CONSUMER','STORE','PURCHASE') and
STG.OMN_APND_KEY='61855975'
Also, if you are merely just trying to update the field STG.last_hit_time_gmt, why not just use two simple UPDATE statements?
UPDATE EDW_STAGE_CDM_SRC.STG_OMNITUREDATA
SET STG.last_hit_time_gmt = DATE '1970-01-01'
WHERE STG.last_hit_time_gmt <> 0
AND UPPER(STG_OMNITUREDATA.EVAR41) IN
('CONS_SUPP: CONSUMER','STORE','PURCHASE')
AND STG.OMN_APND_KEY='61855975';
UPDATE EDW_STAGE_CDM_SRC.STG_OMNITUREDATA
SET STG.last_hit_time_gmt = NULL
WHERE STG.last_hit_time_gmt = 0
AND UPPER(STG_OMNITUREDATA.EVAR41) IN
('CONS_SUPP: CONSUMER','STORE','PURCHASE')
AND STG.OMN_APND_KEY='61855975';

Find statement with alias

I'm trying to group a query's response by day, month, or year based on user input.
To do this I'm extracting the day, month, or year from the log_time column AS when and then trying to GROUP BY when but CakePHP says:
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "when" LINE 1: ...2-31' GROUP BY "Passenger"."route_id", "Route"."name", when ^
Here's an example of my function call where the grouping is 'month'.
$fields = array(
"CONCAT(DATE_PART('year', \"Passenger\".\"log_time\"), '-', DATE_PART('month', \"Passenger\".\"log_time\")) AS when",
"Passenger.route_id",
"Route.name",
"SUM(Passenger.embarked) AS embarked"
);
$conditions = array(
"Passenger.log_time >=" => $start,
"Passenger.log_time <=" => $end
);
$group = array("Passenger.route_id", "Route.name", "\"when\"");
return $this->find('all', array('fields' => $fields, 'conditions' => $conditions, 'group' => $group));
This is using Postgres on Cake 2.3.5. Has anyone else figured out how to do this?
when is a keyword that is used with CASE. Looks like PostgreSQL can figure out that the when in your select is just an identifier but there isn't enough context to figure it out in the GROUP BY. I'd quote it in both places:
"CONCAT(DATE_PART('year', \"Passenger\".\"log_time\"), '-', DATE_PART('month', \"Passenger\".\"log_time\")) AS \"when\"",
and:
$group = array("\"when\"", "Passenger.route_id", "Route.name");

How to make a function in DB2 database to convert an integer to date, and the case when is 0?

I was trying to make a function to work in db2:
CREATE FUNCTION TO_DATE8(DATE_STRING numeric(8,0))
RETURNS DATE
LANGUAGE SQL
IF DATE_STRING > 0 THEN
// ERROR ->
RETURN DATE ( TO_DATE ( SUBSTR ( DATE_STRING , 1 , 8 ) , 'YYYYMMDD' ) )
ELSE
RETURN DATE ( TO_DATE ( '00000000' , 'YYYYMMDD' ) )
END IF
END
ERROR: DATE IS NOT VALID
What to do?
The form of the procedure required seems to be like this (at least on the iSeries version):
CREATE FUNCTION TO_DATE8(DATE_STRING numeric(8,0))
RETURNS DATE
LANGUAGE SQL
BEGIN
RETURN(CASE WHEN DATE_STRING > 0 THEN DATE(SUBSTR(DATE_STRING, 1, 4) || '-' ||
SUBSTR(DATE_STRING, 5, 2) || '-' ||
SUBSTR(DATE_STRING, 7, 2))
ELSE DATE('0001-01-01')
END);
END
However:
Your procedure is misnamed (reading from a date-8, not to it).
Your DATE_STRING is not a string (or even a char), it's numeric. Please rename it to something that does not include the datatype (dateToConvert works)
You seem to want to return something that is not a valid date (all 0s). I'm returning *loval here, although it's possible it should actually be null.
I didn't put in enough checks for a valid date - this will blow up really easily.
If at all possible, the database should be changed to contain actual dates, not a numeric value. Disk is (relative to programmer/architect headaches) cheap.
You may also find a calendar file helpful, if the 8-digit numeric was one of the included columns.
For the benifit of others, this can be done in one line rather than a function:
CASE WHEN MYDATE = 0 THEN NULL ELSE DATE(INSERT(INSERT(LEFT(CHAR(MYDATE),8),5,0,'-'),8,0,'-')) END
MYDATE was 8 packed in my case.