Oracle SQL - using the coalesce function - sql

I really can't get my head around the coalesce function ... or if this is even the best way to get the result I'm trying to achieve.
I have three dates in the following script (iv.dated, iv1.dated, dh.actshpdate). When I run the following script the dates are in separate columns (as expected);
select unique li.catnr, li.av_part_no, li.artist||' / '||li.title description, li.cust_catnr pallet_ref,
trunc(iv.dated), trunc(iv1.dated), trunc(dh.actshpdate)
from leos_item li
left join invtran_view_oes iv
on li.av_part_no = iv.part_no
and (iv.transaction = 'NREC' and iv.location_no = ' RETURNS W')
left join invtran_view_oes iv1
on li.av_part_no = iv1.part_no
and (iv1.transaction = 'CORR+' and iv1.remark like 'STOCK FROM SP PALLET%')
left join oes_delsegview od
on od.catnr = li.catnr
and od.prodtyp = li.prodtyp
and od.packtyp = li.packtyp
left join oes_dpos dp
on od.ordnr = dp.ordnr
and od.posnr = dp.posnr
and od.segnr = dp.segnr
left join oes_dhead dh
on dp.dheadnr = dh.dheadnr
where li.cunr = '816900'
and substr(li.catnr,1,5) in ('RGMCD','RGJCD')
and li.item_type = 'FP'
and li.catnr = 'RGJCD221'
What I would like to achieve is one column with all dates in date order.
I tried replacing my dates with ...
trunc(coalesce(iv.dated, iv1.dated, dh.actshpdate)) transaction_date
... but, I lose some of the dates;
How can I achieve the following result?

You could use UNION in the following way -
WITH DATA AS(
<your query goes here>
)
SELECT A, b, c, d, e FROM DATA
UNION
SELECT A,b,c,d,f FROM DATA
UNION
SELECT A,b,c,d,g FROM DATA
where a, b, c, d, e, f, g are the column alias of the select list in your original query. You can give your own column alias in the UNION query.

Related

Athena query with joins

I am trying to run query on Athena which is not behaving as expected:
select distinct aw.year, aw.month, aw.day
from aw
left join f on aw.c1= f.c1
and aw.c2 = f.c2
and aw.c3 = f.c3
and aw.year = '2022'
and aw.month = '2'
and aw.day = '5'
I am expecting this query to return 2022, 2, 5 but it is returning several other values of year, month and day. The below query works fine and returns only 2022, 2, 5.
select distinct aw.year, aw.month, aw.day
from aw
join f on aw.c1= f.c1
and aw.c2 = f.c2
and aw.c3 = f.c3
and aw.year = '2022'
and aw.month = '2'
and aw.day = '5'
The problem is when I add left join but I am also adding the filer of required year, month and day. I am doing something wrong logically here?
You appear to be confusing conditions within an ON with conditions in a WHERE.
Your left join query returned rows where aw had other values because you were providing conditions for how to join the rows between tables. It does not limit the rows from the 'left' table.
If you only want to return rows where the LEFT table (aw) date matches 2022-02-05, then you should put those conditions in a WHERE:
select distinct aw.year, aw.month, aw.day
from aw
left join f on aw.c1 = f.c1
and aw.c2 = f.c2
and aw.c3 = f.c3
where aw.year = '2022'
and aw.month = '2'
and aw.day = '5'

concatenating one to many values to one line separated by commas in sql join

I have a join which shares a one to many relationship to one table. I would to in stead of returning this value:
125|PROGRAM1|OEM2|1
125|PROGRAM1|OEM2|2
125|PROGRAM1|OEM2|3
I want to return one line like this:
125|PROGRAM1|OEM2|1,2,3
Here is the sql i am running now:
select d.layout_id,d.pgm_nm,d.corp_nm from io_layout_output d
join (select f.program_nm, c.corp_nm from file_config f
join corp_config c
on f.output_id = c.output_id
where f.output_id = 112) b
on d.pgm_nm = b.program_nm and d.corp_nm = b.corp_nm
How would I end up with the correct output?
You need to use a function for that. See LISTAGG
select d.layout_id,
d.pgm_nm,
LISTAGG(d.corp_nm, ', ') as corp_nm
from io_layout_output d
join (select f.program_nm,
c.corp_nm
from file_config f
join corp_config c
on f.output_id = c.output_id
where f.output_id = 112) b
on d.pgm_nm = b.program_nm
and d.corp_nm = b.corp_nm
group by d.layout_id,
d.pgm_nm
EDIT:
Last time I used Oracle you could use LISTAGG using group by. I just looked at the docs and it doesn't mention it anymore. Here is the way if above does not work:
select d.layout_id,
d.pgm_nm,
LISTAGG(d.corp_nm, ', ')
WITHIN GROUP (ORDER BY d.layout_id, d.pgm_nm) as corp_nm
from io_layout_output d
join (select f.program_nm,
c.corp_nm
from file_config f
join corp_config c
on f.output_id = c.output_id
where f.output_id = 112) b
on d.pgm_nm = b.program_nm
and d.corp_nm = b.corp_nm
Note: I'm just showing how to use the function. Did not look at your query at all. Adding this note because your result data does not match the number of columns on your SQL

Remove row from SQL pivot when fields null

The following query below listed generates blank values in a row.
-- Simplify the pivot selection query by separating the query using a with clause
WITH pivot_data AS(
SELECT va.identity,
vc.units,
s.field_name "Sample ID",
s.id_text "Lab ID",
TO_CHAR(str.result_value, S_FORMATMASK_PACKAGE.s_FormatMask(vc.analysis, s.id_numeric))result_value
FROM sample s
LEFT OUTER JOIN client c ON c.id = s.client_id
LEFT OUTER JOIN samp_test_result str ON (s.id_numeric = str.id_numeric
AND s.id_text = str.id_text and str.result_value is not null)
LEFT OUTER JOIN versioned_analysis va ON (va.identity = str.analysis)
LEFT OUTER JOIN versioned_component vc ON (vc.analysis = va.identity
AND vc.analysis_version = va.analysis_version
AND vc.name = str.component_name)
WHERE s.fas_sample_type = sample_pkg.get_leaf_sample
AND s.status = sample_pkg.get_authorised_sample
AND s.flg_released = constant_pkg.get_true
AND vc.flg_report = constant_pkg.get_true
AND c.id = UPPER ('I000009')
AND s.ID_NUMERIC between TO_NUMBER(2126) and TO_NUMBER(12917) and str.result_value <> 0
)
SELECT pvt1.*
FROM(SELECT * FROM pivot_data PIVOT (MAX(result_value) result_value, MAX(units) units FOR identity IN('NIR_N' "Nitrogen",
'XRF_P' "Phosphorus",
'XRF_K' "Potassium",
'XRF_CA' "Calcium",
'XRF_MG' "Magnesium",
'XRF_S' "Sulphur",
'XRF_SI' "Silicon",
'XRF_ZN' "Zinc",
'XRF_MN' "Manganese",
'XRF_CU' "Copper",
'XRF_FE' "Iron"))) pvt1
How do I remove a row that contains null fields

Comparing Query Result With Table and Retrieve Specific Field

My Query
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
Again I would like to compare the query result columns
sStockistCode
sStateName
sDivision
with tblStockistMaster with the same fields
sStockistCode
sStateName
sDivision
and retrieve the STOCKIST NAME.
Don't know how to compare the above query result with the table.
Maybe you can use following SQL code used with CTE expression
;with cte as (
SELECT
stoMast.sStockistCode,
stoMast.sStateName,
stoMast.sDivision,
stateMap.sRMCode
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast ON
stateMap.sStateName = stoMast.sStateName
WHERE
stateMap.sRMCode = 'MCNE04001'
and
stoMast.sDivision = 'CIDIS'
except
select
sStockistCode,
sStateName,
sDivision,
sRMCode
From
tblEntry
)
select
cte.*,
sm.sStockistName
from cte
left join tblStockistMaster as sm
on sm.sStockistCode = cte.sStockistCode and
sm.sStateName = cte.sStateName and
sm.sDivision = cte.sDivision
-- I retrieve the stockist Name
SELECT
stoMast.sStockistName,
FROM
tblRSM_State_Mapping stateMap
INNER JOIN
tblStockistMaster stoMast
ON stateMap.sStateName = stoMast.sStateName
-- I'm joining table entry If I can match
LEFT JOIN
tblEntry tbl
on tbl.sStockistCode = stoMast.sStockistName
AND tbl.sStateName = stoMast.sStateName
AND tbl.sDivision = stoMast.sDivision
AND tbl.sRMCode = stateMap.sRMCode
WHERE
stateMap.sRMCode = 'MCNE04001'
and stoMast.sDivision = 'CIDIS'
-- And The the exept thing, I don't want that got a match with the tableentry
AND COALESCE(tbl.sStockistCode, tbl.sStateName, tbl.sDivision, tbl.sRMCode) is null
I expect it is what you wanted to get. On another way please help us understand wht you come from (tables and idea of what data can be in) and the result you want. Will be easier to create a query.

Group By clause error in Select query

Given below is my select query in PostgreSQL
SELECT
gtab12.AcGrCode,
gtab12.AcId,
gtab12.AcName,
gtab11.AcgrName,
gtab16.VrDate,
gtab16.PDC,
cast(gtab16.VrDate as char(12)) as vdate,
gtab16.VrNo,
gtab16.Refno,
gtab02.VrName,
gtab17.Narr,
CASE WHEN gtab16.VrId = 6 THEN 0::decimal ELSE gtab17.Dr::decimal END AS Dr,
CASE WHEN gtab16.VrId = 6 THEN 0::decimal ELSE gtab17.Cr::decimal END AS Cr,
gtab16.AcyrId, gtab16.VrId,
coalesce(SUM(gtab17.Dr), 0::money) AS OpDr,
coalesce(SUM(gtab17.Cr), 0::money) AS OpCr ,
coalesce(SUM(gtab17.Dr), 0::money)AS OpperDr,
coalesce(SUM(gtab17.Cr), 0::money)AS OpperCr,
gtab47.AreaName,
gtab16.JrmId
FROM
gtab16
INNER JOIN gtab02 ON gtab16.VrId = gtab02.VrId
INNER JOIN gtab17 ON gtab16.JrMId = gtab17.JrmId
INNER JOIN gtab12 ON gtab17.AcId = gtab12.AcId
INNER JOIN gtab11 ON gtab12.AcGrCode = gtab11.AcgrCode
INNER JOIN gtab01 ON gtab16.AcyrId = gtab01.AcYrId
LEFT OUTER JOIN gtab22 ON gtab16.RepId = gtab22.RepId
LEFT OUTER JOIN gtab47 ON gtab12.AreaId = gtab47.AreaId
WHERE
(gtab17.AcId = gtab12.AcId) and gtab16.BranchID = 1 And vrdate Between
Cast('2014-04-01' AS timestamp) AND Cast('2014-09-27' AS timestamp) AND
(gtab16.AcYrId = 7) AND gtab16.VrId <> 6 And gtab12.acid <> 0
when executing am getting this error
ERROR: column "gtab12.acgrcode" must appear in the GROUP BY clause or
be used in an aggregate function
Note : before modifying this query the aggreagte functions are gathering from sub selects see it here
You are using aggregate functions (SUM) in some columns so you need to use aggregates functions on other ones or group by columns.
Bye, David.