Filtering subquery results - sql

I'm having a problems filtering the duplicate values from my query. This is my query
SELECT cid.IDS_NO,cid.SUB_TITLE,cid.E_SUB_NAME, (cid.SUB_TITLE || ' '|| cid.E_SUB_NAME),
(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE))
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1),
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1),
('COUNTRY' ||' ' || pl_post),pl_post
FROM SUBSCRIBER cid where pl_postal_district = 15 and rownum < 3001
and hi_property_type IN ('CONDO','COMMERCIAL BUILDING');
These are the parts I'm having problems with:
(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE))
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1),
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1);
These parts always get multiple records, and I want to get only 1 record with the lowest sequence number, So here's what I did:
(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE))
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1 ORDER BY d.SEQ_NO DESC),
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1 ORDER BY d.SEQ_NO DESC);
But I always get an error saying missing parenthesis, but when I remove the order by, it works fine. What should I do to get my query running correctly?

Formatting your query to make it easier to read goes a long way to begin with.
But you also have a rather tricky problem, since you ..
want to get only 1 record with the lowest sequence number.
Should work like this:
SELECT s.ids_no
,s.sub_title
,s.e_sub_name
,(s.sub_title || ' '|| s.e_sub_name) AS title_sub_name
,d.some_col_name
,t.inst_name
,('COUNTRY' ||' ' || s.pl_post) AS country_post
,s.pl_post
FROM subscriber s
LEFT JOIN (
SELECT d.ids_no
,(d.inst_blk_hse || ' ' || st.e_street_name) AS some_col_name
,ROW_NUMBER() OVER (PARTITION BY d.ids_no ORDER BY d.seq_no) AS rn
FROM del d
LEFT JOIN e_street_name st ON st.street_code = d.inst_st_code
) d ON d.ids_no = s.ids_no AND d.rn = 1
LEFT JOIN (
SELECT ids_no
,(inst_st_level || '-' || inst_stunit) AS inst_name
,ROW_NUMBER() OVER (PARTITION BY d.ids_no ORDER BY d.seq_no) AS rn
FROM detail
) t ON t.ids_no = s.ids_no AND t.rn = 1
WHERE s.pl_postal_district = 15
AND s.rownum < 3001
AND s.hi_property_type IN ('CONDO','COMMERCIAL BUILDING');
More details on how the subqueries work under this related question:
Select first row in each GROUP BY group?
The core features is ROW_NUMBER() to get the record with the lowest sequence number.
I rewrote your correlated subqueries, because they generally suck performance-wise. They are also hard to read.
I use LEFT JOIN, so you still get a row in case the subquery shouldn't find anything to match.

Subqueries must return only one row. So you have to add rownum = 1 to the subquery that is inside the subquery FROM del d. Something like:
SELECT
cid.IDS_NO,
cid.SUB_TITLE,
cid.E_SUB_NAME,
(cid.SUB_TITLE || ' '|| cid.E_SUB_NAME),
(SELECT (INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME
FROM street_table
where street_code = d.INST_ST_CODE
and rownum = 1)) <<<<<<< here
FROM del d
where d.IDS_NO = cid.IDS_NO
and ROWNUM = 1),
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT
FROM detail d
where d.IDS_NO = cid.IDS_NO
and rownum = 1),
('COUNTRY' ||' ' || pl_post),
pl_post
FROM SUBSCRIBER cid
where pl_postal_district = 15
and rownum < 3001
and hi_property_type IN ('CONDO','COMMERCIAL BUILDING');
Or, JOIN all the tables like this:
SELECT
cid.IDS_NO,
cid.SUB_TITLE,
cid.E_SUB_NAME,
cid.SUB_TITLE || ' '|| cid.E_SUB_NAME,
d.INST_BLK_HSE || ' ' || s.E_STREET_NAME,
d.INST_ST_LEVEL || '-' || d.INST_STUNIT
'COUNTRY' ||' ' || pl_post),
pl_post
FROM SUBSCRIBER cid
INNER JOIN del d ON d.IDS_NO = cid.IDS_NO
INNER JOIN detail d2 ON d2.IDS_NO = cid.IDS_NO
INNER JOIN street_table s ON s.street_code = d.INST_ST_CODE
WHERE cid.pl_postal_district = 15
and cid.rownum < 3001
and cid.hi_property_type IN ('CONDO','COMMERCIAL BUILDING')
and s.rownum = 1
and d.rownum = 1
and d2.rownum = 1;

Related

Could you help me to solve this simple join issue?i am new to sql so no idea what is wrong with this

SELECT LEVEL_A.VALUE,LEVEL_B.VALUE,LEVEL_C.VALUE,LEVEL_C.VALUE
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM LEVEL_C
ON H.VALUE_LIST_HEADER_NO = LEVEL_C.VALUE_LIST_HEADER_NO
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'SERVER_ENTITY'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_A
ON LEVEL_A.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1)
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'PurchaseType'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_B
ON LEVEL_B.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1) || '#' ||
REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 2)
WHERE H.CAPTION = 'PurchaseSubCategoryList'
AND LOWER(NVL(LEVEL_C.DESCRIPTION, ' ')) NOT LIKE '%disabled%'
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'PurchaseCategoryList'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_D
ON LEVEL_D.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1) || '#' ||
REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 2) || '#' || REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 3)
WHERE H.CAPTION = 'PurchaseSubCategoryList'
AND LOWER(NVL(LEVEL_C.DESCRIPTION, ' ')) NOT LIKE '%disabled%'
ORDER BY LEVEL_C.VALUE ASC;
First, where is the call of table "LEVEL_A" by some FROM command? This can be corrupting all code. When you input a name with dot and another one, it mean as 'tableName.columnName'. I hope help.

Oracle SQL Developer query not sorting alphabetically

My query:
SELECT
pmmr.REQUEST_NO, pmmr.item_code itemCode, Pmmr.Form_No Form_No,
NVL(Pmf.Form_Name, Pmmr.Form_No) formName, pmmr.MRN,
NVL(p.FIRST_NAME || DECODE(p.FAMILY_NAME, NULL, '', ' ' || p.FAMILY_NAME),pmmr.MRN) PATIENT_NAME,
pmmr.ASSIGNED_TO, pmmr.DRUG_GENERIC_NAME, pmmr.LAST_STATUS,
NVL(initcap(( hr1.FIRST_NAME || ' ' || hr1.LAST_NAME)), pmmr.LAST_PERFORMER_ID) LastActionBy,
NVL(hr2.DEPARTMENT || ' - ' || hr2.SECTION_NAME,'') ORGANIZATION_UNIT,
NVL(initcap(( hr2.FIRST_NAME || ' ' || hr2.LAST_NAME)), pmmr.REQUESTER_ID) RequesterName,
pmmr.REQUEST_DATE
FROM
inhouse_apps.PHRM_MFRP_MEDICATION_REQUEST pmmr
LEFT OUTER JOIN
inhouse_apps.Hr_Employee hr1 ON Pmmr.Last_Performer_Id = Hr1.Employee_Number
LEFT OUTER JOIN
inhouse_apps.Hr_Employee hr2 ON inhouse_apps.Pmmr.Requester_Id = Hr2.Employee_Number
LEFT OUTER JOIN
EAPPTMT.PATIENT p ON inhouse_apps.Pmmr.Mrn = P.Mrn
LEFT OUTER JOIN
inhouse_apps.Phrm_Mfrp_Form pmf ON Pmmr.Form_No = Pmf.Form_No;
WHERE
LAST_STATUS IN ('Approved')
AND Pmmr.Form_No = 2
ORDER BY
pmmr.DRUG_GENERIC_NAME ASC
I need the DRUG_GENERIC_NAME sorted alphabetically, but it's not returning the result sorted ..
EDIT: as mentioned below the semicolon needed to be removed, that's all
You have semicolon ";" before your "Where clause". You need to remove it from there to make Oracle take account of both your "Where clause" and your "Order by clause"
SELECT pmmr.REQUEST_NO, pmmr.item_code itemCode, Pmmr.Form_No Form_No, nvl(Pmf.Form_Name, Pmmr.Form_No) formName, pmmr.MRN, nvl (p.FIRST_NAME || DECODE(p.FAMILY_NAME, NULL, '', ' ' || p.FAMILY_NAME),pmmr.MRN) PATIENT_NAME,pmmr.ASSIGNED_TO,
pmmr.DRUG_GENERIC_NAME,pmmr.LAST_STATUS, nvl(initcap(( hr1.FIRST_NAME || ' ' || hr1.LAST_NAME)),pmmr.LAST_PERFORMER_ID) LastActionBy,
nvl(hr2.DEPARTMENT || ' - ' || hr2.SECTION_NAME,'') ORGANIZATION_UNIT, nvl(initcap(( hr2.FIRST_NAME || ' ' || hr2.LAST_NAME)),pmmr.REQUESTER_ID) RequesterName, pmmr.REQUEST_DATE
FROM inhouse_apps.PHRM_MFRP_MEDICATION_REQUEST pmmr
left outer join inhouse_apps.Hr_Employee hr1 on Pmmr.Last_Performer_Id = Hr1.Employee_Number
left outer join inhouse_apps.Hr_Employee hr2 on inhouse_apps.Pmmr.Requester_Id = Hr2.Employee_Number
left outer join EAPPTMT.PATIENT p on inhouse_apps.Pmmr.Mrn = P.Mrn
left outer join inhouse_apps.Phrm_Mfrp_Form pmf on Pmmr.Form_No = Pmf.Form_No
WHERE LAST_STATUS IN ('Approved')
and Pmmr.Form_No = 2
order by pmmr.DRUG_GENERIC_NAME ASC
;

using xmlagg to find count to concatenate

SELECT DISTINCT
ent.entity_key_id AS query1kid,
CAST(substr(rtrim(XMLAGG(xmlelement(e,alstd.relationship_desc
||
CASE
WHEN(alstd.joint_flag = 'No' AND ent.anonymous_flag = 'No') THEN ''
ELSE('('
||
CASE
WHEN alstd.joint_flag = 'Yes' THEN 'Joint'
ELSE ''
END
||
CASE
WHEN ent.anonymous_flag = 'Yes' THEN ',Anon'
ELSE ''
END
|| ')')
END
|| ': '
|| allocthm.allocation_description
|| '('
|| substr(allocthm.allocation_code,5,6) || ***count(ben.entity_key_ID)***
|| ')',',').extract('//text()')
ORDER BY
ent.entity_key_id
).getclobval(),','),1,4000) AS VARCHAR(4000) ) AS displayfiled1
FROM
er_datamart.allocation_theme allocthm
left JOIN er_datamart.allocation_stewardee alstd ON (allocthm.allocation_code = alstd.allocation_code and alstd.status_code <> 'F')
INNER JOIN er_datamart.entity_d ent ON alstd.entity_key_id = ent.entity_key_id
LEFT OUTER JOIN ER_DATAMART.ALLOCATION_BENEFICIARY ben ON ben.allocation_code = allocthm.allocation_code
GROUP BY
ent.entity_key_id
This gives me an error:
ORA-00937: not a single-group group function
I'm trying to find the count(ben.entity_key_ID) so that I can have it appended to my already functional query. Any help would be appreciated.
The problem seems to be the count() inside the xmlagg() - you have nested group functions that the group-by clause can't handle.
You can move the string concatenation into an inline view with its own group-by to get that count, and then perform the XML aggregation from that; something like:
SELECT
entity_key_id AS query1kid,
CAST(substr(rtrim(
XMLAGG(xmlelement(e, constructed_string, ',').extract('//text()')
ORDER BY entity_key_id
).getclobval(),','),1,4000) AS VARCHAR(4000) ) AS displayfiled1
FROM (
SELECT ent.entity_key_id,
alstd.relationship_desc
||
CASE
WHEN(alstd.joint_flag = 'No' AND ent.anonymous_flag = 'No') THEN ''
ELSE('('
||
CASE
WHEN alstd.joint_flag = 'Yes' THEN 'Joint'
ELSE ''
END
||
CASE
WHEN ent.anonymous_flag = 'Yes' THEN ',Anon'
ELSE ''
END
|| ')')
END
|| ': '
|| allocthm.allocation_description
|| '('
|| substr(allocthm.allocation_code,5,6) || count(ben.entity_key_ID)
|| ')' as constructed_string
FROM
allocation_theme allocthm
LEFT JOIN allocation_stewardee alstd
ON allocthm.allocation_code = alstd.allocation_code and alstd.status_code <> 'F'
INNER JOIN entity_d ent
ON alstd.entity_key_id = ent.entity_key_id
LEFT OUTER JOIN ALLOCATION_BENEFICIARY ben
ON ben.allocation_code = allocthm.allocation_code
GROUP BY
ent.entity_key_id,
alstd.relationship_desc,
alstd.joint_flag,
ent.anonymous_flag,
allocthm.allocation_description,
allocthm.allocation_code
)
GROUP BY
entity_key_id
The ELSE '' parts are redundant as that is the default behaviour but you might prefer to keep them for clarity/explicitness. Your joint/anon part might need a bit more work - if joint is No and anon is Yes you get (,Anon) - I think - which looks a bit odd, but might be what you need.

Nested Query Sql Oracle Sort

Can anyone give me right syntax to sort this query? I want to sort base on column DocNum desc and LineNo asc
Thanks
select distinct * from (
select a.ildoc"DocNum", replace(round(a.illnid/1000,2),',','.')"LineNo",
replace(round(a.iltgn/1000,2),',','.')"TrnsctionGroup",
case when a.ilfrto = 'F' then
'From'
else
'To'
end"F/T",
a.ilitm"Item", c.imdsc1"Desc",
replace(round(a.iltrqt/10000,2),',','.')"Qty", a.illotn"LotSerial",
case when INSTR(a.illotn,': ') = 0 then
' '
else
to_char(substr(a.illotn,INSTR(a.illotn,': ')+2))
end"Serial",
d.iolot1"Memo1", d.iolot2"Memo2"
from proddta.f4111 a
inner join proddta.f4111 e on a.ildoc = e.ildoc
inner join proddta.f4101 c on c.IMITM = a.ilitm
left join proddta.f4108 d on a.illotn = d.iolotn and d.iomcu = a.ilmcu and
d.ioITM = a.ilitm
where a.ilmcu = 18001 and a.ildct = 'IE'
and e.ilitm = 56233
order by a.ildoc desc, a.iljeln asc
)--order by a.ildoc"DocNum" desc, a.iljeln asc
SELECT DISTINCT *
FROM ( SELECT a.ildoc
"DocNum",
REPLACE (ROUND (a.illnid / 1000, 2), ',', '.')
"LineNo",
REPLACE (ROUND (a.iltgn / 1000, 2), ',', '.')
"TrnsctionGroup",
CASE WHEN a.ilfrto = 'F' THEN 'From' ELSE 'To' END
"F/T",
a.ilitm
"Item",
c.imdsc1
"Desc",
REPLACE (ROUND (a.iltrqt / 10000, 2), ',', '.')
"Qty",
a.illotn
"LotSerial",
CASE
WHEN INSTR (a.illotn, ': ') = 0
THEN
' '
ELSE
TO_CHAR (
SUBSTR (a.illotn, INSTR (a.illotn, ': ') + 2))
END
"Serial",
d.iolot1
"Memo1",
d.iolot2
"Memo2"
FROM proddta.f4111 a
INNER JOIN proddta.f4111 e ON a.ildoc = e.ildoc
INNER JOIN proddta.f4101 c ON c.IMITM = a.ilitm
LEFT JOIN proddta.f4108 d
ON a.illotn = d.iolotn
AND d.iomcu = a.ilmcu
AND d.ioITM = a.ilitm
WHERE a.ilmcu = 18001 AND a.ildct = 'IE' AND e.ilitm = 56233
ORDER BY "DocNum" DESC, a.iljeln ASC)

ORA-00920 [42000]: invalid relational operator

Here is the SQL Source Code for database selection that generates the following
error: "Query execution failed, Reason: SQL Error [920] [42000]:
ORA-00920: opérateur relationnel non valide.
Please Help!
WITH adr_siege as (
SELECT Nvl(adr.libadr, ' ') AS libadr, Nvl(adr.adress, ' ') AS adress,
Nvl(adr.codpos, ' ') AS codpos, Nvl(adr.locali, ' ') AS locali,
Nvl(adr.codpay, ' ') AS codpay
FROM gnx.tie
JOIN gnx.adr
ON adr.codsoc = tie.codsoc
AND adr.typtie = tie.typtie
AND adr.sigadr = tie.sigtie
AND typadr = 'COM'
WHERE tie.typtie = 'DEP'
AND tie.codsoc=1
AND tie.sigtie = '00000137'
)
SELECT Nvl(a.codpro, ' ') AS codpro, Nvl(a.nompro, ' ') AS nompro,
Nvl(ll.prix_achat, 0) AS prix_achat, Nvl(ll.qte, 0) AS qte,
Nvl(l.nom_fournisseur, ' ') AS nom_fournisseur, Nvl(m.raison, ' ') AS raison,
Nvl(concat(m.adresse1,' ' || m.adresse2), ' ') AS adresse_mag,
Nvl(m.cp, ' ') AS cp, Nvl(m.ville, ' ') AS ville,
Nvl(p.libelle, ' ') AS libelle,
Nvl(To_Char(c.date_validation, 'DD/MM/YYYY'), ' ') AS date_validation,
Nvl((
SELECT sum(fll.prix_achat * fll.qte)
FROM fourniture.frnt_livraison_ligne fll
WHERE fll.noliv
), 0) AS total_prix,
To_Char(SYSDATE, 'DD/MM/YYYY') AS date_edition,
Nvl(f.libadr, ' ') AS fou_lib_adr,
Nvl(f.tel, ' ') AS fou_tel,
Nvl(f.adress, ' ') AS fou_adr, Nvl(f.codpos, ' ') AS fou_cp,
Nvl(f.locali, ' ') AS fou_ville, Nvl(pf.libelle, ' ') AS fou_pays,
Nvl(to_char(p.date_livraison_s1, 'DD/MM/YYYY'), ' ') AS date_livraison_s1,
Nvl(to_char(p.date_livraison_s2, 'DD/MM/YYYY'), ' ') AS date_livraison_s2,
Nvl((
SELECT tbl.lib1
FROM gnx.tie
LEFT JOIN gnx.tbl
ON tbl.codtbl = 'mrg'
AND tbl.lib1 IS NOT NULL
AND tbl.codsoc=1
AND tbl.cletbl = tie.modrgl
WHERE tie.typtie = 'FOU'
AND tie.sigtie = l.code_fournisseur
AND tie.codsoc =1
), ' ') AS mode_paiement,
l.num_sous_periode,
adr_siege.*,
Nvl(m.nummag, ' ') AS nummag,
Nvl(m.tel1, ' ') AS tel1,
l.ref_gnx,
Nvl(tva.taux_tva, 0)/100 AS taux_tva,
Nvl(f.code, ' ') AS code_fournisseur,
(
CASE WHEN (m.lundi_ouverture != '0' OR m.mardi_ouverture != '0' OR m.mercredi_ouverture != '0'
OR m.jeudi_ouverture != '0' OR m.vendredi_ouverture != '0' OR m.samedi_ouverture != '0') THEN 1
ELSE 0
END
) AS AFFICH_HORRAIRE,
a.conditionnement,
a.refpro as REFPRO
FROM adr_siege, fourniture.frnt_livraison l
INNER JOIN fourniture.frnt_livraison_ligne ll ON ll.noliv = l.noliv
INNER JOIN fourniture.frnt_article a ON a.codpro = ll.codpro
INNER JOIN fourniture.frnt_commande c ON c.nocde = l.nocde
INNER JOIN polymag.magasin m ON m.nummag = c.nummag
INNER JOIN polymag.pays p ON p.code = m.codepays
LEFT JOIN fourniture.frnt_fournisseur f ON f.code =l.code_fournisseur
INNER JOIN polymag.pays pf ON pf.code = f.codpay
INNER JOIN fourniture.frnt_periode p ON p.noperiode = c.noperiode
LEFT JOIN fourniture.frnt_tva tva ON tva.code_pays_fou = f.codpay AND tva.code_pays_mag = m.codepays
WHERE l.type_livraison = 'FOU'
(we are selecting in schema named 'fournisseur')
Thank you in advance for your help.
problem is at line 25 because of WHERE fll.noliv that's without any relational operator like <,>,!,= after this statement.
TOTAL_PRIX seems to be invalid; look at its WHERE clause:
(
SELECT SUM(fll.prix_achat * fll.qte)
FROM fourniture.frnt_livraison_ligne fll
WHERE fll.noliv ), 0) AS total_prix,