Case Expression and dates - sql

I have the below case expression.
SELECT end_dt,
CASE WHEN TO_CHAR(A.END_DT,'MM/DD/YYYY') = '01/01/3000' THEN ''
WHEN TO_CHAR(A.END_DT,'MM/DD/YYYY') > TO_CHAR(SYSDATE,'MM/DD/YYYY') THEN TO_CHAR(SYSDATE,'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT,'MM/DD/YYYY')
END ENDDATE,
CASE WHEN TO_CHAR(A.END_DT,'YYYYMM') = '300001' THEN ''
WHEN TO_CHAR(A.END_DT,'YYYYMM') > TO_CHAR(SYSDATE,'YYYYMM') THEN TO_CHAR(SYSDATE,'YYYYMM')
ELSE TO_CHAR(A.END_DT,'YYYYMM')
END ENDDATE_YYYYMM,
CASE WHEN TO_CHAR(A.END_DT,'YYYY') = '3000' THEN ''
WHEN TO_CHAR(A.END_DT,'YYYY') > TO_CHAR(SYSDATE,'YYYY') THEN TO_CHAR(SYSDATE,'YYYY')
WHEN TO_CHAR(A.END_DT,'YYYY') > TO_CHAR(SYSDATE,'YYYY') THEN TO_CHAR(SYSDATE,'YYYY')
ELSE TO_CHAR(A.END_DT,'YYYY')
END ENDDATE_YYYY
FROM A
LEFT D ON A.ID = D.ID
WHERE 1=1
ORDER BY 1
OutPut:
End_dt ENDDATE ENDDATE_YYYYMM ENDDATE_YYYY
12/5/2012 14:33:24 01/05/2018 201212 2012
Expected output:
End_dt ENDDATE ENDDATE_YYYYMM ENDDATE_YYYY
12/5/2012 14:33:24 12/5/2012 201212 2012
Why do I get a result of 01/05/2018 and not 12/5/2012?

You're doing string comparisons on dates. Stop. Do date comparisons on dates.
The string '12/5/2012' is greater than the string '01/05/2018' because 1 is greater than 0. Oracle is performing a binary comparison.
SQL> select *
2 from dual
3 where '12/5/2012' > '01/05/2018';
D
-
X
Stop converting all your dates to strings and all will be well
SQL> select *
2 from dual
3 where date '2018-05-01' > date '2012-05-12';
D
-
X
Incidentally, the empty string '' is equivalent to NULL in Oracle.
Your query should look like:
CASE WHEN A.END_DT = date '3000-01-01' then null
WHEN A.END_DT > SYSDATE THEN TO_CHAR(SYSDATE,'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT,'MM/DD/YYYY')
END ENDDATE,

Don't do date comparisons as strings. It works for the other values, because you have the right format -- YYYYMMDD (or a partial piece of that).
Try this logic:
SELECT end_dt,
(CASE WHEN TO_CHAR(A.END_DT, 'MM/DD/YYYY') = '01/01/3000' THEN ''
WHEN A.END_DT > SYSDATE
THEN TO_CHAR(SYSDATE, 'MM/DD/YYYY')
ELSE TO_CHAR(A.END_DT, 'MM/DD/YYYY')
END) as ENDDATE,
(CASE WHEN TO_CHAR(A.END_DT, 'YYYYMM') = '300001' THEN ''
WHEN TO_CHAR(A.END_DT, 'YYYYMM') > TO_CHAR(SYSDATE, 'YYYYMM')
THEN TO_CHAR(SYSDATE,'YYYYMM')
ELSE TO_CHAR(A.END_DT,'YYYYMM')
END) as ENDDATE_YYYYMM,
(CASE WHEN TO_CHAR(A.END_DT, 'YYYY') = '3000' THEN ''
WHEN TO_CHAR(A.END_DT, 'YYYY') > TO_CHAR(SYSDATE, 'YYYY')
THEN TO_CHAR(SYSDATE, 'YYYY')
WHEN TO_CHAR(A.END_DT, 'YYYY') > TO_CHAR(SYSDATE,'YYYY')
THEN TO_CHAR(SYSDATE, 'YYYY')
ELSE TO_CHAR(A.END_DT, 'YYYY')
END) as ENDDATE_YYYY

Related

How to insert a dynamic where clause within a case when in ATHENA

i have this query
SELECT case
when {{aggtime}} = 'HOURLY' then parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyyMMddHH'), 'yyyyMMddHH')
when {{aggtime}} = 'DAILY' then CAST("PUBLIC"."ORDERS"."CREATED_AT" AS date)
when {{aggtime}} = 'WEEKLY' then dateadd('day', CAST((1 - CASE WHEN ((iso_day_of_week("PUBLIC"."ORDERS"."CREATED_AT") + 1) % 7) = 0 THEN 7 ELSE ((iso_day_of_week("PUBLIC"."ORDERS"."CREATED_AT") + 1) % 7) END) AS long), CAST("PUBLIC"."ORDERS"."CREATED_AT" AS date))
when {{aggtime}} = 'MONTHLY' then parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyyMM'), 'yyyyMM')
when {{aggtime}} = 'YEARLY' then parsedatetime(formatdatetime("PUBLIC"."ORDERS"."CREATED_AT", 'yyyy'), 'yyyy')
END
AS "CREATED_AT", sum("PUBLIC"."ORDERS"."QUANTITY") AS "sum"
FROM "PUBLIC"."ORDERS"
WHERE year(CREATED_AT)=2020 and month(CREATED_AT) = 1 and day(CREATED_AT) = 01
GROUP BY "CREATED_AT"
i need the where clause only when {{aggtime}}='HOURLY', otherwise i need only the year
How can i achieve it ?
ps :. {{aggtime}} is a parameter for Metabase

How can I get different data with case?

In view If lokasyonno= 27 , I want the first block to run, if not the second block. How can I do it?
I tried to do it with the switch case structure, but I couldn't get a result because there is no common column.
FIRST
SELECT round(UH.NETTUTAR)
FROM TBL_IRSALIYE IR
INNER JOIN TBL_URUNHAREKETLERI UH ON UH.IRSALIYEID = IR.IRSALIYEID
INNER JOIN TBL_URUNLER U ON UH.URUNID = U.URUNID
WHERE IR.LOKASYONNO = 27
AND IR.TUR = 7
AND IR.IPTAL = 0
AND IR.ONAY = 1
AND IR.BILLED = 1
AND IR.INTERNET = 60
AND ROWNUM <= 10
AND IR.TARIH > TO_DATE ('2020-09-27 ', 'yyyy-mm-dd ')
AND IR.TARIH <= TO_DATE ('2020-10-05', 'yyyy-mm-dd ')
second
NVL (
(SELECT ROUND (
SUM (
CASE DOCUMENT_TYPE
WHEN 2
THEN
(CASE TRANSACTION_TYPE
WHEN 0
THEN
0
- ( LINE_TOTAL_VALUE
- LINE_TOTL_DISCOUNT)
ELSE
LINE_TOTAL_VALUE
- LINE_TOTL_DISCOUNT
END)
ELSE
(CASE TRANSACTION_TYPE
WHEN 1
THEN
0
- ( LINE_TOTAL_VALUE
- LINE_TOTL_DISCOUNT)
ELSE
( LINE_TOTAL_VALUE
- LINE_TOTL_DISCOUNT)
END)
END),
10)
FROM TBL_TRANSACTION_LINES
WHERE (TRANSACTION_TYPE NOT IN (10, 30))
AND STORE_NO = LOK.LOKASYONNO
AND (URUNID = TBL_URUNLER.URUNID)
AND TRANSACTION_DATE >
TO_DATE ('2020-09-27 0:0:0',
'yyyy-mm-dd HH24:MI:SS')
AND TRANSACTION_DATE <=
TO_DATE ('2020-10-04 0:0:0',
'yyyy-mm-dd HH24:MI:SS')),
0)
AS HAFTALIKKASASATISTUTARI
Use a union of the two queries but add a not exists() on the first query as an additional condition of the second query:
<first query>
union all
<second query>
where not exists (<first query>)

Pivot without aggregate function

I am trying to turn some parts of my rows into columns. To my knowledge, I am only able to use a pivot with an aggregate function,but I would just be pivoting text. For each client I have up to 4 rows grouped by a DLSEQUENCE field. Instead of having the 4 rows, I would like everything to be on 1 row.
SELECT CASE
WHEN Sched_time BETWEEN TRUNC(SCHED_TIME) + INTERVAL '8' HOUR + INTERVAL '30' MINUTE
AND TRUNC(SCHED_TIME) + INTERVAL '14' HOUR + INTERVAL '45' MINUTE AND
TO_CHAR(SCHED_TIME, 'DY') IN ('MON', 'TUE', 'WED', 'THU', 'FRI')
THEN 'ABC'
ELSE 'DEF'
END AS Organization,
Client_Last_Name,
Client_First_Name,
Sched_Time,
Field_Name,
CASE
WHEN Recoded_Response = '1' THEN 'Yes'
WHEN Recoded_Response = '2' THEN 'No'
ELSE Recoded_Response
END AS Responses,
Dlsequence
FROM DAILY_LOG_CUSTOM_DATA
WHERE SERVICE_NAME = 'Medical'
AND FIELD_CATEGORY = 'Background Information'
AND Field_Name IN
(
'Restraint?',
'History',
'Findings',
'Treatment'
)
AND Sched_Time >= TO_DATE('2020-03-01 01:00:00', 'YYYY/MM/DD HH:MI:SS')
AND Sched_Time < TO_DATE('2020-03-31 12:59:00', 'YYYY/MM/DD HH:MI:SS')
Order BY Dlsequence
Here is my table:
I would like the response fields that go with ('Restraint?','History','Findings','Treatment') to have their own column for each DLSEQUENCE field.
The following should do what you had in mind:
SELECT DLSEQUENCE,
ORGANIZATION,
CLIENT_LAST_NAME,
CLIENT_FIRST_NAME,
SCHED_TIME,
LISTAGG("Restraint?", ',') WITHIN GROUP (ORDER BY DLSEQUENCE) AS "Restraint?",
LISTAGG("Findings", ',') WITHIN GROUP (ORDER BY DLSEQUENCE) AS "Findings",
LISTAGG("History", ',') WITHIN GROUP (ORDER BY DLSEQUENCE) AS "History",
LISTAGG("Treatment", ',') WITHIN GROUP (ORDER BY DLSEQUENCE) AS "Treatment"
FROM (SELECT DLSEQUENCE,
ORGANIZATION,
CLIENT_LAST_NAME,
CLIENT_FIRST_NAME,
SCHED_TIME,
CASE
WHEN FIELD_NAME = 'Restraint?' THEN RESPONSES
ELSE NULL
END AS "Restraint?",
CASE
WHEN FIELD_NAME = 'Findings' THEN RESPONSES
ELSE NULL
END AS "Findings",
CASE
WHEN FIELD_NAME = 'History' THEN RESPONSES
ELSE NULL
END AS "History",
CASE
WHEN FIELD_NAME = 'Treatment' THEN RESPONSES
ELSE NULL
END AS "Treatment"
FROM YOUR_TABLE)
GROUP BY DLSEQUENCE,
ORGANIZATION,
CLIENT_LAST_NAME,
CLIENT_FIRST_NAME,
SCHED_TIME
db<>fiddle here

ora-02287 Sequence number not allowed

I am trying to run the following query to fill a table with the proper values. I have ran the select statement alone, without the price_s and the created_by, creation_date, last_updated_by, and last_update_date, and it pulls everything that I need. When I add those values, it gives errors, I have gotten through some of them, but I am stuck on this one ORA-02287: Sequence number not allowed here, I have looked everywhere and cannot find what I am doing wrong. It is probably some simple answer, but I just cannot see it right now.
Here is the code:
CREATE SEQUENCE price_s START WITH 1001;
INSERT INTO price (price_id, item_id, price_type, active_flag, start_date, end_date, amount, created_by, creation_date, last_updated_by, last_update_date)
SELECT price_s.nextval, i.item_id,
active_flag,
cl.common_lookup_id,TRUNC (i.release_date),
CASE
WHEN (TRUNC (SYSDATE) - TRUNC (i.release_date)) < 31 AND active_flag = 'N' THEN NULL
WHEN (TRUNC (SYSDATE) - TRUNC (i.release_date)) > 30 AND active_flag = 'N' THEN TRUNC (i.release_date) + 30
END AS END_DATE,
CASE
WHEN (TRUNC (SYSDATE) - TRUNC (i.release_date)) < 31 AND active_flag = 'Y' THEN
CASE
WHEN rental_days = 1 THEN '3'
WHEN rental_days = 3 THEN '10'
WHEN rental_days = 5 THEN '15'
END
WHEN (TRUNC (SYSDATE) - TRUNC (i.release_date)) > 30 AND active_flag = 'N' THEN
CASE
WHEN rental_days = 1 THEN '3'
WHEN rental_days = 3 THEN '10'
WHEN rental_days = 5 THEN '15'
END
WHEN (TRUNC (SYSDATE) - TRUNC (i.release_date)) > 30 AND active_flag = 'Y' THEN
CASE
WHEN rental_days = 1 THEN '1'
WHEN rental_days = 3 THEN '3'
WHEN rental_days = 5 THEN '5'
END
END AS AMOUNT,
1,SYSDATE,1,SYSDATE
FROM item i CROSS JOIN
(SELECT 'Y' AS active_flag FROM dual
UNION ALL
SELECT 'N' AS active_flag FROM dual) af CROSS JOIN
(SELECT '1' AS rental_days FROM dual
UNION ALL
SELECT '3' AS rental_days FROM dual
UNION ALL
SELECT '5' AS rental_days FROM dual) dr INNER JOIN
common_lookup cl ON dr.rental_days = SUBSTR(cl.common_lookup_type,1,1)
WHERE NOT ((TRUNC (SYSDATE) - TRUNC (i.release_date)) <= 31 AND active_flag = 'N')
AND NOT cl.common_lookup_table = 'RENTAL_ITEM'
ORDER BY 1, 2, 3;
Any ideas on what I am doing wrong?
Well I figured out what was wrong with my statement. I knew it was simple I just could not see it at the time. I forgot to take out the
ORDER BY 1, 2, 3; it was messing everything up, sorry to take up anyone's time.

oracle date function to append month and year

Hi have query like this now i want to append value in query so tran_date is in Date time format in databases: so consider these two query
query 1:: i have to append value in date format but it not working ..how to pass year and month in date type::
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and to_date(TRAN_DATE, 'yyyy') = '2013'
AND to_date(TRAN_DATE, 'MON') = 'APR'
OR to_date(TRAN_DATE, 'yyyy') = '2013'
AND to_date(TRAN_DATE, 'MON') = 'MAR'
GROUP BY TRAN_DATE
query 2: its work but it is string format
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and (to_char(TRAN_DATE, 'yyyy') = '2013' AND
to_char(TRAN_DATE, 'MON') = 'APR')
OR (to_char(TRAN_DATE, 'yyyy') = '2013' AND
to_char(TRAN_DATE, 'MON') = 'MAR')
GROUP BY TRAN_DATE
One of options is to use BETWEEN condition with DATETIME datatype columns:
select TRAN_DATE,
trunc(nvl(SUM(SALES_VALUE), 0) + nvl(sum(total_sales), 0) -
nvl(sum(net_sales), 0) + nvl(sum(discount), 0)) Sale
from OUTLET_PAYMODE_REPORT_FACT A, OUTLET_DETAILS B
WHERE A.OUTLET_ID = B.OUTLET_ID
and SALES_VALUE > 0
and TRAN_DATE between to_date('01.03.2013', 'dd.mm.yyyy') and
to_date('30.04.2013', 'dd.mm.yyyy')
GROUP BY TRAN_DATE;