Input data to complicated join table dbgrid - oracle

I have a dbgrid that I am going to use as input method for my application. Query to that goes by this:
select a.tanggal,
(case a.kode
when '01' then
a.jumlah
else
null
end) as SERATUSRIBU,
(case a.kode
when '02' then
a.jumlah
else
null
end) as LIMAPULUHRIBU,
(case a.kode
when '03' then
a.jumlah
else
null
end) as DUAPULUHRIBU,
(case a.kode
when '04' then
a.jumlah
else
null
end) as SEPULUHRIBU,
(case a.kode
when '05' then
a.jumlah
else
null
end) as LIMARIBU,
(case a.kode
when '06' then
a.jumlah
else
null
end) as DUARIBU,
(case a.kode
when '07' then
a.jumlah
else
null
end) as SATURIBU,
b.jumlahfisik,
b.selisih,
b.bon,
b.uangrusak,
b.materai,
b.lain,
b.jumlahtotal
from kasir_opname_detail a
left outer join kasir_opname_header b
on a.tanggal = b.tanggal
where a.ptlokasi = '0';
This dbgrid will be a field where I can get values to save the data into database. (Not using apply updates, but using a button with insert code in it). However, the columns where I use the case code cannot be filled with anything.
Is there any idea how to put data to those columns? Or is there any other way to make it possible?

Related

need to use case when for select document path for two type?

HOW TO WRITE QUERY
SELECT DOC_PATH,
(CASE WHEN DOCTYPE=1 THEN SCAN_PATH from documents where DOC_NO='A112' AND ROWNUM=1 END) AS DOCS,
(CASE WHEN DOCTYPE=2 THEN SCAN_PATH from documents where DOC_NO='B331' AND ROWNUM=1 END) AS DOCS
FROM documents
The structure of your query implies that you should be doing an aggregation:
SELECT
DOC_PATH,
MAX(CASE WHEN DOCTYPE = 1 AND DOC_NO = 'A112' THEN SCAN_PATH END) AS DOCS1,
MAX(CASE WHEN DOCTYPE = 2 AND DOC_NO = 'B331' THEN SCAN_PATH END) AS DOCS2
FROM documents
GROUP BY DOC_PATH;

PLSQL Case in Where clause for >= (date)

I am using a table that contains various milestones to determine the stages of a contract. Each milestone has a date, and I need to build a report on a handful of those milestones to determine the average length of time it takes for a project to get from one stage to another. The table contains information spanning from 1996 onward, and I'm only interested in projects that have been finalized (milestone 4.08) in the past year.
The trouble is I can't seem to build a case statement that looks for a particular milestone, and then filters the date that corresponds to it. Below is the code I'm working on.
Select Distinct CONSTRUCTION.CONTRACTS.CONTRACTNUMBER,
CONSTRUCTION.TBL_CONTRACTPROJECTCOMBO.LOCATIONS,
Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'3.02' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End) RECEIVED_IN_AUDIT,
Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.04' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End) INITIAL_AUDIT_COMPLETE,
Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.08' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End) FINAL_AUDIT_COMPLETE,
(Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.08' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End) - (Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'3.02' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End))) DAYS_IN_AUDIT,
(Case
When Extract(Month From Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.08' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End)) >= 7 Then
Extract(Year From Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.08' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End)) + 1
Else
Extract(Year From Max(Case
When CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER =
'4.08' Then
CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE
End))
End) FY_AUDIT_COMPLETE
From CONSTRUCTION.CONTRACTS
Join CONSTRUCTION.CONTRACTMILESTONES on CONSTRUCTION.CONTRACTMILESTONES.CONTRACTID = CONSTRUCTION.CONTRACTS.ID
Join CONSTRUCTION.MILESTONEEVENTS on CONSTRUCTION.MILESTONEEVENTS.ID = CONSTRUCTION.CONTRACTMILESTONES.MILESTONEID
Join CONSTRUCTION.TBL_CONTRACTPROJECTCOMBO on CONSTRUCTION.TBL_CONTRACTPROJECTCOMBO.CONTRACTNUMBER = CONSTRUCTION.CONTRACTS.CONTRACTNUMBER
Where (CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER = '4.04' Or
CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER = '4.08' Or
CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER = '3.02')
And (case when CONSTRUCTION.MILESTONEEVENTS.MILESTONENUMBER = '4.08'
then CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE >= sysdate-365 END)
Group By CONSTRUCTION.CONTRACTS.CONTRACTNUMBER,
CONSTRUCTION.TBL_CONTRACTPROJECTCOMBO.LOCATIONS
The error I get is
ORA-00905: missing keyword.
The error indicates that my code breaks between the CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE and the ">=". What am I doing wrong?
Any help is appreciated. Thank you.
Aliases exist for reason; I suggest you use them and make queries you write easier to read.
As of a problem you have: I believe this solves part of it:
SELECT DISTINCT c.contractnumber,
m.milestone,
m.milestonedescription,
cm.milestonedate,
m.milestonenumber
FROM construction.contracts c
JOIN construction.contractmilestones cm ON cm.contractid = c.id
JOIN construction.milestoneevents m ON m.id = cm.milestoneid
WHERE cm.milestonedate >=
CASE WHEN m.milestonenumber = '4.08' THEN TRUNC (SYSDATE) - 365
ELSE DATE '2021-01-01' --> if it isn't 4.08, what should CM.MILESTONEDATE be larger than?
END
CASE you wrote is wrong because it should represent some condition, while your query tries to use it, but in a wrong manner (you can't have THEN within the CASE).
Note ELSE I wrote; I used date literal (Jan 1st 2021) because I don't know what you want to do with other milestones (different from 4.08). If you do (you should, right?), put that date in there.
I guess you have extra bracket here at end..
then CONSTRUCTION.CONTRACTMILESTONES.MILESTONEDATE >= to_date(to_char(sysdate, 'mm/dd/yyyy'), 'mm/dd/yyyy')-365) END)
Can you try removing and executing same query again.

Oracle store procedure to retrieve dates ny passing column name as parameter

The below procedure returns thousands of lines by passing start date and end date. Added to that i need to add one parameter which should apply the start date and end date on different columns such as created date, planned date and end date which are available in result set.
For instance if i pass the value as (created date,'31/10/2020 00:00:00','01/11/2020 00:00:00'), the filter should be applied on created date column, if i pass (end,'31/10/2020 00:00:00','01/11/2020 00:00:00'), the filter should be applied on end date column.
How can i achieve this ?
create or replace PROCEDURE CVP_TEST(STARTDATE VARCHAR, ENDDATE VARCHAR) AS
st_dt TIMESTAMP := TO_TIMESTAMP(STARTDATE, 'dd/mm/yyyy hh24:mi:ss');
end_dt TIMESTAMP := TO_TIMESTAMP(ENDDATE, 'dd/mm/yyyy hh24:mi:ss');
cursor cur1(start_time timestamp, end_time timestamp)
is
SELECT
A.LGST_GRP_CD ,
(case when A.FRST_SHPG_LOC_CD like 'D%' then A.FRST_SHPG_LOC_CD
when (A.FRST_SHPG_LOC_CD not like 'D%' and A.DMCL_CD is not null and length(dmcl_t.shpgloc_cd) <= 4) then dmcl_t.shpgloc_cd
--when (A.FRST_SHPG_LOC_CD not like 'D%' and A.DMCL_CD is null and length(dom_carrier.shpgloc_cd) <= 4) then dom_carrier.shpgloc_cd
else A.FRST_SHPG_LOC_CD end) AS Dispatch_DC,
--ba_tmextra.FUN_GET_INT_DC(A.LD_LEG_ID) AS INT_DC,
'XXX' AS INT_DC,
A.CUR_OPTLSTAT_ID,
--V.CUR_STAT_ID,
A.TRIP_ID AS TRIP_ID,
A.LD_LEG_ID AS LOAD_ID,
A.CARR_CD AS CARRIER_ID,
A.SRVC_CD AS SERVICE_ID,
A.EQMT_TYP AS EQMT_TYP,
A.STRD_DTT AS START_DATE,
A.END_DTT AS END_DTT,
A.CRTD_DTT AS CRTD_DTT,
A.TRCTR_NUM as TRCTR_NUM,
A.DRVR as DRVR,
A.TRLR_NUM,
A.FRST_SHPG_LOC_CD,
A.LAST_SHPG_LOC_CD,
A.NUM_STOP as NUM_STOP,
--BA_TMEXTRA.FUN_GET_STOP_LOC(A.LD_LEG_ID, 0) STOP_LIST,
'XXX' AS STOP_LIST,
LD_MMO.PRTB_CTNT AS LD_COMMENTS,
A.MILE_DIST AS MILE_DIST,
A.TOT_SCLD_WGT AS TOTAL_WEIGHT,
A.ELPD_HRS,
CM.chrg_extl_code2 as chrg_extl_code2,
(case when CM.chrg_extl_code2 = 'HAUL' then C.CHRG_CD else null end) as Haul_Charge_ID,
(case when CM.chrg_extl_code2 = 'HAUL' then C.CHGD_UNIT_RATE else null end) as Planned_Rate,
(case when CM.chrg_extl_code2 = 'FUEL' then C.CHGD_UNIT_RATE else null end) as Fuel_Planned_Rate,
(case when CM.chrg_extl_code2 = 'FUEL' then C.CHRG_CD else null end) as Fuel_Surcharge_Type_ID,
(case when CM.chrg_extl_code2 = 'STOP' then C.CHRG_CD else null end) as Stop_Off_Charge_ID,
--C.CHRG_CD AS CHRG_CD,
--C.CHGD_UNIT_RATE AS PLANNED_RATE,
NVL(C.MNLY_OVRD_DLR,0) as CHRG_GRP_AMT
FROM JDATM_PROD.LD_LEG_T A, JDATM_PROD.CHRG_DETL_T C, JDATM_PROD.IA_DIST_MSTRCHRG CM,
JDATM_PROD.DMCL_T,
--DMCL_T DOM_CARRIER,
--VCHR_AP_T V,
JDATM_PROD.MMO_T LD_MMO
WHERE 1=1
AND A.LD_LEG_ID = C.LD_LEG_ID
AND C.CHRG_CD = CM.CHRG_CODE
AND C.CHRGDETL_TYP_ENU = 1
AND C.CHRG_LVL_ENU != 7
AND A.DMCL_CD=DMCL_T.DMCL_CD(+)
--AND DOM_CARRIER.CARR_CD(+)=A.CARR_CD
--AND V.VCHR_NUM (+) = C.VCHR_NUM_AP
--AND V.CUR_STAT_ID (+) != 825
and A.mmo_id = ld_mmo.mmo_id (+)
AND A.TRIP_ID IS NULL
--AND A.LD_LEG_ID = 1001038103
AND A.RATG_VLID_YN = 'T'
AND A.STRD_DTT BETWEEN start_time and end_time;
read_value cur1%ROWTYPE;
BEGIN
--dbms_output.put_line('Accepted:' || STARTDATE || ', ' || ENDDATE);
--dbms_output.put_line('Assigned:' || st_dt || ', ' || end_dt);
END;
You can use the OR condition as follows:
AND (
(P_IN_COLUMN_NAME = 'created date' AND A.CREATED_DTT BETWEEN start_time and end_time)
OR
(P_IN_COLUMN_NAME = 'planned date' AND A.PLANNED_DTT BETWEEN start_time and end_time )
)

oracle SQL procedure updating table

I need to update the the following columns in a table. males,females,infants and children using SQL procedure.from this column paxtype which has f,i,m,c.which is females,infants,males and children repectively.but am not able error ORA-00907: missing right parenthesis
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT b.PAXTYPE, COUNT (b.PAXTYPE) FROM xxxx b
(case ( count (b.PAXTYPE))
when ( count (b.PAXTYPE))='M'then 'a.males'
when ( count (b.PAXTYPE))='F' then 'a.females'
when ( count (b.PAXTYPE))='I' then 'a.infants'
when ( count (b.PAXTYPE))='C' then 'a.children'
END)
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE;
)
It looks like you want a total count of each type, right? I think this is what you want to do.
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT
sum(case when b.PAXTYPE = 'I' then 1 else 0 end) as infants_count,
sum(case when b.PAXTYPE = 'M' then 1 else 0 end) as males_count,
sum(case when b.PAXTYPE = 'C' then 1 else 0 end) as children_count,
sum(case when b.PAXTYPE = 'F' then 1 else 0 end) as females_count
FROM xxxx b
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE);

Oracle/SQL Query issue

I am sort of a newbie to oracle/sql. I am trying to pull from the same column different values and add them with some other information. The other information is not the issue it is trying to count and add here the problem comes in.
I am connecting to an oracle database. Here is what i have
SELECT
EV.PUBLIC_DESCRIPTION,
EV.EVENT_DATE,
ES.PRICE,
BT.BUYER_TYPE_CODE,
PCA.ADDR1,
PCA.ADDR2,
PCA.CITY,
PCA.POSTAL_CODE,
PCE.EMAIL,
PC.FORMATTED_NAME,
PCP.PHONE_NUMBER,
PCP.SECONDARY,
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADLT' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADTE' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GSTDTE' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GROUDI' THEN 1 ELSE 0 END)) AS "Adults",
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCHILD' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCHTE' THEN 1 ELSE 0 END)) AS 'Paid Child',
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRPCH' THEN 1 ELSE 0 END)) AS 'Free Child',
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCOMP' THEN 1 ELSE 0 END)) AS 'Comps'
FROM EVENT EV
INNER JOIN EVENT_SEAT ES ON EV.EVENT_ID = ES.EVENT_ID
INNER JOIN BUYER_TYPE BT ON ES.BUYER_TYPE_ID = BT.BUYER_TYPE_ID
INNER JOIN PATRON_ORDER PO ON ES.ORDER_ID = PO.ORDER_ID
INNER JOIN PATRON_ACCOUNT PA ON ES.ATTENDING_PATRON_ACCOUNT_ID = PA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT PC ON PA.PATRON_ACCOUNT_ID = PC.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_ADDRESS PCA ON PC.PATRON_ACCOUNT_ID = PCA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_EMAIL PCE ON PCA.PATRON_ACCOUNT_ID = PCE.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_PHONE PCP ON PCE.PATRON_ACCOUNT_ID = PCP.PATRON_ACCOUNT_ID
GROUP BY EV.PUBLIC_DESCRIPTION, EV.EVENT_DATE
ORDER BY ES.TRANSACTION_ID DESC, PCP.SECONDARY DESC, PCP.PHONE_NUMBER DESC, PC.FORMATTED_NAME DESC, PCE.EMAIL DESC, PCA.POSTAL_CODE DESC, PCA.CITY DESC, PCA.ADDR2 DESC, PCA.ADDR1 DESC, BT.BUYER_TYPE_CODE DESC, ES.PRICE DESC;
any help would be greatly appreciated
You need to decide which technique you want to use, currently you are using 2 techniques and they are colliding.
For this you must know: COUNT() will increment by one for every NON-NULL value
So, to use COUNT() with a case expression do this
COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 END)
or
COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE NULL END)
OR, don't use COUNT(), use SUM() instead
SUM(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE 0 END)
To add conditions together, I suggest you use the case expression better
Instead of something like this:
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADLT' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADTE' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GSTDTE' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GROUDI' THEN 1 END) AS "Adults"
Use this:
COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRADLT','GRADTE','GRSTND','GSTDTE','GROUDI') THEN 1 ELSE NULL END)
There is also an issue with your GROUP BY, which MUST contain ALL non-aggregating columns. I think your query should look more like this:
SELECT
EV.PUBLIC_DESCRIPTION
, EV.EVENT_DATE
, ES.PRICE
/* , BT.BUYER_TYPE_CODE */
, PCA.ADDR1
, PCA.ADDR2
, PCA.CITY
, PCA.POSTAL_CODE
, PCE.EMAIL
, PC.FORMATTED_NAME
, PCP.PHONE_NUMBER
, PCP.SECONDARY
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRADLT', 'GRADTE', 'GRSTND', 'GSTDTE', 'GROUDI') THEN 1 ELSE NULL END) AS "Adults"
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRCHILD', 'GRCHTE', 'GRPCH', 'GRCOMP') THEN 1 ELSE NULL END) AS "Free Child"
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCOMP' THEN 1 ELSE NULL END) AS "Comps"
FROM EVENT EV
INNER JOIN EVENT_SEAT ES
ON EV.EVENT_ID = ES.EVENT_ID
INNER JOIN BUYER_TYPE BT
ON ES.BUYER_TYPE_ID = BT.BUYER_TYPE_ID
INNER JOIN PATRON_ORDER PO
ON ES.ORDER_ID = PO.ORDER_ID
INNER JOIN PATRON_ACCOUNT PA
ON ES.ATTENDING_PATRON_ACCOUNT_ID = PA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT PC
ON PA.PATRON_ACCOUNT_ID = PC.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_ADDRESS PCA
ON PC.PATRON_ACCOUNT_ID = PCA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_EMAIL PCE
ON PCA.PATRON_ACCOUNT_ID = PCE.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_PHONE PCP
ON PCE.PATRON_ACCOUNT_ID = PCP.PATRON_ACCOUNT_ID
GROUP BY
EV.PUBLIC_DESCRIPTION
, EV.EVENT_DATE
, ES.PRICE
/* , BT.BUYER_TYPE_CODE */
, PCA.ADDR1
, PCA.ADDR2
, PCA.CITY
, PCA.POSTAL_CODE
, PCE.EMAIL
, PC.FORMATTED_NAME
, PCP.PHONE_NUMBER
, PCP.SECONDARY
/* check all these columns exist in the select clause
ORDER BY
ES.TRANSACTION_ID DESC
, PCP.SECONDARY DESC
, PCP.PHONE_NUMBER DESC
, PC.FORMATTED_NAME DESC
, PCE.EMAIL DESC
, PCA.POSTAL_CODE DESC
, PCA.CITY DESC
, PCA.ADDR2 DESC
, PCA.ADDR1 DESC
, BT.BUYER_TYPE_CODE DESC
, ES.PRICE DESC
*/
When you come the the final clause: ORDER BY you can ONLY reference columns that exist in the select clause. This example would FAIL
select column1 from table1 group by column1 order by fred
but this would work:
select column1 from table1 group by column1 order by column1
Your column aliases 'Paid Child', 'Free Child', 'Comps' should not be wrapped in single quotes. You should be using double quotes like you are already for "Adults".
So they should instead be:
"Paid Child"
"Free Child"
"Comps"
Or better yet, consider naming your aliases without any spaces, so you don't have to worry about wrapping the aliases in anything, like this:
paid_child
free_child
comps
Documentation on Database Object Names and Qualifiers:
Database Object Naming Rules
Every database object has a name. In a SQL statement, you represent the name of an object with a quoted identifier or a nonquoted identifier.
A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.
A nonquoted identifier is not surrounded by any punctuation.
...
Although column aliases, table aliases, usernames, and passwords are not objects or parts of objects, they must also follow these naming rules unless otherwise specified in the rules themselves.

Resources