postgresql if else select query - sql

I am trying to make a query that will compare first
first condition was to compare
the year now and
get the maximum year of view view_delinquency_allquarter
then, it will execute the first query
else second query
BEGIN
IF
select max(ctaxyear) as ctaxyear,
(select cast ( (SELECT EXTRACT(QUARTER FROM TIMESTAMP 'now()')) as int ) as yearnow) as yearnow
from view_delinquency_allquarter
where ctaxyear > year_next
THEN
select * from view_delinquency_allquarter;
ELSE
select * from view_delinquency;
END IF;
END

There are plenty of answers as well as documentation use declare var and then assignment var := (your query result)

Related

DB2 i 7.3: writing stored procedures that loop (with date variable) insert values from select

I'm having problem to create procedure in db2 i 7.3. The main ideia is to a given end date (should be today) to insert values to specific table from selected that results match with fist_day(end date - 3 years) and last_day(end date - 3 years) for every month until today.
Is currently returning this error: 14:19:25 [CREATE - 0 row(s), 0.000 secs] [Error Code: -199, SQL State: 42601] [SQL0199] Palavra-chave FOR não esperada. Testemunhos válidos: ;.
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec [0 successful, 0 warnings, 1 errors]
Above my code:
CREATE PROCEDURE MYLIB.SP_DIFJURO ()
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
DECLARE DATAJURO DATE DEFAULT NULL;
FOR DATAJURO > (SELECT CURRENT_DATE - 3 YEAR FROM SYSIBM.SYSDUMMY1)
DO
INSERT INTO MYLIB.SDDIFJUROD (CONTAJURO, JUROCALC, JURODEBIT, DATAINICIO, DATAFIM)
SELECT NCJCCONTA, totaljurocalculado, NCLJVLRJ, LEFT(CHAR(LAST_DAY(DATAJURO), ISO),8)||'01', LAST_DAY(DATAJURO) FROM ( SELECT SUM(valorjurocalculado) totaljurocalculado, a.NCJCCONTA from
(SELECT C.NCJCCONTA NCJCCONTA, C.NCJCDTPRO, C.NCJCDTJUR,
CASE
WHEN R.NCJCTREG = 'R' THEN R.NCJCSLDV
ELSE C.NCJCSLDV
END saldodatavalor,
CASE
WHEN R.NCJCTREG = 'R' THEN round(R.NCJCTXC,2)
ELSE round(C.NCJCTXC,2)
END taxadiaria, decimal(round((ifnull(R.NCJCSLDV, C.NCJCSLDV)*ifnull(R.NCJCTXC, C.NCJCTXC)/100)/360,2),15,2) valorjurocalculado
FROM (
SELECT NCJCCONTA, NCJCDTPRO, NCJCDTJUR, NCJCTREG, NCJCSLDV, NCJCMOED, NCJCTXC FROM MYLIB.LOGJR
WHERE NCJCDTJUR BETWEEN LEFT(VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD'),6)||'01' AND VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD')
AND NCJCCLCP = 'DO' AND NCJCTREG = 'C' AND NCJCNUMVD < 0 ) C
LEFT JOIN
(SELECT NCJCCONTA, NCJCDTPRO, NCJCDTJUR, NCJCTREG, NCJCSLDV, NCJCMOED, NCJCTXC FROM MYLIB.LOGJR
WHERE NCJCDTJUR BETWEEN LEFT(VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD'),6)||'01' AND VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD')
AND NCJCCLCP = 'DO' AND NCJCTREG = 'R' AND NCJCNUMVD < 0) R
ON C.NCJCCONTA = R.NCJCCONTA AND C.NCJCDTJUR = R.NCJCDTJUR
) a group by a.NCJCCONTA
)jurocalc
INNER JOIN MYLIB.LJRDC ON NCLJCONTA = NCJCCONTA
AND LEFT(NCLJBUFFER, 16) = LEFT(VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD'),6)||'01'||VARCHAR_FORMAT(LAST_DAY(DATAJURO), 'YYYYMMDD')
WHERE int(ABS(totaljurocalculado)) != int(ABS(NCLJVLRJ));
SET DATAJURO = (SELECT DATAJURO - 1 MONTH FROM SYSIBM.SYSDUMMY1);
END FOR;
END
Wrong use of FOR statement.
FOR in SQL/PL doesn't look like for loop in some programming language like c or java. You must use a SELECT statement with FOR, which iterates the result set of this SELECT providing you an ability to reference the corresponding column values in the statements inside the body of FOR by cursor name C1.
In the example below the SELECT statement using Recursive Common Table Expression returns the last day of every month from CURRENT_DATE - 3 YEARS to CURRENT_DATE. You may run this SELECT standalone to check / slightly modify its condition to return exact list of dates needed.
Note, that you don't use a SET statement to increment your "loop variable" C1.DATAJURO, since the SELECT statement handles this.
FOR C1 AS
WITH DATES (DT) AS
(
VALUES FIRST_DAY(CURRENT_DATE)
UNION ALL
SELECT DT - 1 MONTH
FROM DATES
WHERE DT > CURRENT_DATE - 3 YEAR
)
SELECT LAST_DAY(DT) AS DATAJURO
FROM DATES
DO
INSERT INTO MYLIB.SDDIFJUROD ...
... C1.DATAJURO ...
END FOR;

Select Query in if else in Postgres Sql

something like ths
if(1=1)
select * from Table_a
else
slect * from Table_b
without using functions
I am trying something like this
DO $$
DECLARE
a integer := 10;
b integer := 20;
BEGIN
IF a >b THEN
select * from online.fandi_workflow_options ;
else
select * from online.credit_workflow_options ;
END IF;
END
$$;
Can anyone help me here
select * from online.fandi_workflow_options
where a > b
union
select * from online.credit_workflow_options
where a <= b
You can usually replace a logical "if" with a "where" clause; in your case, you're selecting from two different tables, so you have to use a union. This query only works if both tables have the same columns - if not, you can select explicit column names, and add "bogus" columns to each select statement to make them identical.

Error with SELECT statement in a FOR loop

When I try to execute the code below I receive this error here:
Error(9,4): PLS-00103: Encountered the symbol "SELECT" when expecting
one of the following: ( ) - + case mod new not null table continue avg count current exists max min prior sql
stddev sum variance execute multiset the both leading trailing
forall merge year month day hour minute second timezone_hour
timezone_minute timezone_region timezone_abbr time timestamp
interval date
CREATE OR REPLACE PROCEDURE PROC_LIST_SIMILAR_TVSERIES
(seriesName IN SERIES.NAME%TYPE)
AS
CURSOR series IS (SELECT IDS FROM SERIES WHERE NAME = seriesName);
allSeries SERIES%ROWTYPE;
BEGIN
FOR series IN allSeries
(SELECT 2* ( SELECT COUNT(*)
FROM DICT d
WHERE d.idt IN ( SELECT DISTINCT IDT
FROM POSTING
WHERE IDS = series
INTERSECT
SELECT DISTINCT IDT
FROM POSTING
WHERE IDS = allSeries.IDS
)
)
/ ( ( SELECT DISTINCT COUNT(IDT)
FROM POSTING
WHERE IDS = series
) +
( SELECT DISTINCT COUNT(IDT)
FROM POSTING
WHERE IDS = allSeries.IDS )
)
INTO similarity
FROM SERIES s1
SERIES s2
WHERE s1.IDS = series
AND s2.IDS != series
);
IF similarity > 0.7 THEN
DBMS_OUTPUT.PUT_LINE('ok');
END LOOP;
END;
/
What the code does is take in a name, find it's ID, and compare it to other id's (and avoid comparing it to the same ID). I'm trying to print out "ok" whenever the similarity calculation is over 0.7 . No idea why this doesn't work.
First, if you have a cursor named the same as the table, what is the series%rowtype going to look like? The cursor or the table? Bad idea.
Second, you never execute the cursor to get the ID, so your subsequent cursor loop is looking for records that match allSeries.IDS which is null because you haven't populated it.
Try this as a starting point, although I'm guessing that you still will have work to do on your cursor query. Still, at least it points you to the right code structures...
CREATE OR REPLACE PROCEDURE PROC_LIST_SIMILAR_TVSERIES
(seriesName IN SERIES.NAME%TYPE)
AS
CURSOR seriesCur IS (SELECT IDS FROM SERIES WHERE NAME = seriesName);
allSeries seriesCur%ROWTYPE;
BEGIN
OPEN seriesCur;
FETCH seriesCur INTO allSeries;
IF seriesCur%NOTFOUND
THEN
CLOSE seriesCur;
raise_application_error(-20001,'Your SeriesName does not exist');
END IF;
CLOSE seriesCur;
FOR seriesRec IN
-- this query is a mess! Tried to fix up some aspects of it according to what I THINK you're trying to do.
(SELECT 2*
(SELECT COUNT(*) FROM DICT d WHERE d.idt IN (
SELECT DISTINCT IDT FROM POSTING WHERE IDS = allSeries.IDS
INTERSECT
SELECT DISTINCT IDT FROM POSTING WHERE IDS = allSeries.IDS))
/ ((SELECT DISTINCT COUNT(IDT) FROM POSTING WHERE IDS = allSeries.IDS) +
(SELECT DISTINCT COUNT(IDT) FROM POSTING WHERE IDS = allSeries.IDS) ) similarity
FROM SERIES s1, SERIES s2
WHERE s1.IDS = allSeries.IDS
AND s2.IDS != allSeries.IDS)
LOOP
IF seriesRec.similarity > 0.7 THEN
DBMS_OUTPUT.PUT_LINE('ok');
END IF;
END LOOP;
END;
/
I am still trying to understand the logic in the SQL statement. But i
have hopefully tried to remove the syntactical error. Hope it helps.
CREATE OR REPLACE PROCEDURE PROC_LIST_SIMILAR_TVSERIES(
seriesName IN SERIES.NAME%TYPE)
AS
similarity PLS_INTEGER;
BEGIN
FOR i IN
(SELECT IDS FROM SERIES WHERE NAME = seriesName
)
LOOP
--The logic i am still not able to understand
SELECT *,
(SELECT COUNT(*)
FROM DICT d
WHERE d.idt IN
( SELECT DISTINCT IDT FROM POSTING WHERE IDS = I.IDS
INTERSECT
SELECT DISTINCT IDT
FROM POSTING
WHERE IDS = allSeries.IDS
) / (
(SELECT DISTINCT COUNT(IDT) FROM POSTING WHERE IDS = i.IDS
) +
(SELECT DISTINCT COUNT(IDT) FROM POSTING WHERE IDS = I.IDS
) )
)
INTO similarity
FROM SERIES s1,
SERIES s2
WHERE s1.IDS = s2.IDS
AND s2.IDS != I.IDS;
IF similarity > 0.7 THEN
DBMS_OUTPUT.PUT_LINE('ok');
END IF;
END LOOP;
END;
/

SQL Query: finding the 'day' value from a SQL DateTime

I have a table with the fields timeout and timein. I need to return a list of records where timeout is on a different day to timein. How can I achieve this?
If both dates are in the same month, then:
select *
from table
where DAY(timeout) <> DAY(timein0)
or
select *
from table
where DATEPART(day,timeout) <> DATAPART(day,timein) or
will work..
If, however, they can be in different months, then you need to compare the full dates. This should do that for you:
select *
from table
where DATEDIFF(day,timeout,timein) <> 0
select *
from table_name
where datediff(dd,timein,timeout) > 0 (for day in greater then today)
if want next day time out then
select *
from table_name
where datediff(dd,timein,timeout) =1
How about this :
select *
from table
where day(timeout) != day(timein);

SQL Query to return one of two select statements

I have a query that uses a UNION ALL to return results from two different select statements.
I would like to set this up to return only the first select results, and if this first select is empty then return the results of the second select statement.
Can someone give me a simple example of how I might do this.
Thanks in advance
Brian
This checks your first query for a record returned, then executes it. Otherwise it executes the second query.
DECLARE #FirstCount int
SET #FirstCount = (SELECT COUNT (*) FROM <First query>)
IF #FirstCount > 0
BEGIN
<first query here>
END
ELSE
BEGIN
<Second query here>
END
You can also use a table variable like so:
DECLARE #FirstQuery TABLE
(
<fields>
)
SET #FirstQuery = <First Query>
IF EXISTS (SELECT * FROM #FirstQuery)
BEGIN
SELECT * FROM #FirstQuery
END
ELSE
BEGIN
<Second query here>
END
Assuming that you want a query and not a batch, you could duplicate the 1st query of your Union in the second query to determine if it yielded results, and make the 2nd query conditional on that.
E.g. only show shipments if there are no order, otherwise show both (makes no business sense, but shows the point):
select id from tb_shipment
union all
select id from tb_order where 0 = (select COUNT(*) from tb_shipment)
Without knowing your data, I cannot say if there are more efficient ways for you than a WHERE clause.