ORACLE ALIAS in WHERE Clause Subquery [duplicate] - sql

This question already has answers here:
Using an Alias in a WHERE clause
(5 answers)
Closed 9 months ago.
Here is my SQL code.
I used subquery and labeled it, but when I call column from that subquery, it shows that as invalid identifier.
SELECT TSR.Merchant_id, denomination, SUM (no_of_cards)
FROM sales_details
WHERE invoice_id IN (
SELECT invoice_id
FROM sales_header TSR
WHERE entered_by = (
(SELECT account_code
FROM bk_dsr_account_codes
WHERE user_name = 'C'
AND PASSWORD = 'D'
AND mobile_no = '8994035090213391259'))
AND entered_date BETWEEN (TO_DATE ('2013/04/01', 'yyyy/mm/dd')
)
AND (TO_DATE ('2013/06/30', 'yyyy/mm/dd')
))
GROUP BY denomination
error as per below
ORA-00904: "TSR"."MERCHANT_ID": invalid identifier
Please help me to sort out this issue.
I need to call subquery's columns also in my final SQL view.

You can only use colums that are in your FROM clause. So, your query should be something like:
SELECT TSR.Merchant_id, SD.denomination, SUM (SD.no_of_cards)
FROM sales_details SD
JOIN sales_header TSR on SD.invoice_od = TSR.invoice_id
WHERE entered_by = (
(SELECT account_code
FROM bk_dsr_account_codes
WHERE user_name = 'C'
AND PASSWORD = 'D'
AND mobile_no = '8994035090213391259'))
AND entered_date BETWEEN (TO_DATE ('2013/04/01', 'yyyy/mm/dd')
)
AND (TO_DATE ('2013/06/30', 'yyyy/mm/dd')
)
GROUP BY SD.denomination

select * from table1, table2 where table1.userid=x and table2.sdsd=x
also
select * from table1 t1, table2 t2 where t1.userid=x and t2.sdsd=x
same output these 2 above...
try this
SELECT TSR.Merchant_id, denomination, SUM (no_of_cards)
FROM sales_details,TSR
WHERE invoice_id IN (
SELECT invoice_id
FROM sales_header TSR
WHERE entered_by = (
(SELECT account_code
FROM bk_dsr_account_codes
WHERE user_name = 'C'
AND PASSWORD = 'D'
AND mobile_no = '8994035090213391259'))
AND entered_date BETWEEN (TO_DATE ('2013/04/01', 'yyyy/mm/dd')
)
AND (TO_DATE ('2013/06/30', 'yyyy/mm/dd')
))
GROUP BY denomination

Related

Query error: Column name ICUSTAY_ID is ambiguous. Using multiple subqueries in BigQuery

Hi, I receive the following query error "Query error: Column name ICUSTAY_ID is ambiguous" referred to the third last line of code (see the following code). Please can you help me? Thank you so much!
I am an SQL beginner..
WITH t AS
(
SELECT
*
FROM
(
SELECT *,
DATETIME_DIFF(CHARTTIME, INTIME, MINUTE) AS pi_recorded
FROM
(
SELECT
*
FROM
(
SELECT * FROM
(SELECT i.SUBJECT_ID, p.dob, i.hadm_id, p.GENDER, a.ETHNICITY, a.ADMITTIME, a.INSURANCE, i.ICUSTAY_ID,
i.DBSOURCE, i.INTIME, DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) AS age,
CASE
WHEN DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) <= 32485
THEN 'adult'
WHEN DATETIME_DIFF(a.ADMITTIME, p.DOB, DAY) > 32485
then '>89'
END AS age_group
FROM `project.mimic3.ICUSTAYS` AS i
INNER JOIN `project.mimic3.PATIENTS` AS p ON i.SUBJECT_ID = p.SUBJECT_ID
INNER JOIN `project.mimic3.ADMISSIONS` AS a ON i.HADM_ID = a.HADM_ID)
WHERE age >= 6570
) AS t1
LEFT JOIN
(
SELECT ITEMID, ICUSTAY_ID, CHARTTIME, VALUE, FROM `project.mimic3.CHARTEVENTS`
WHERE ITEMID = 551 OR ITEMID = 552 OR ITEMID = 553 OR ITEMID = 224631
OR ITEMID = 224965 OR ITEMID = 224966
) AS t2
ON t1.ICUSTAY_ID = t2.ICUSTAY_ID
)
)
WHERE ITEMID IN (552, 553, 224965, 224966) AND pi_recorded <= 1440
)
SELECT ICUSTAY_ID #### Query error: Column name ICUSTAY_ID is ambiguous
FROM t
GROUP BY ICUSTAY_ID;
Both t1 and t2 have a column called ICUSTAY_ID. When you join them together into a single dataset you end up with 2 columns with the same name - which obviously can't work as there would be no way of uniquely identify each column.
You need to alias these columns in you code or not include one or the other if you don't need both

how to compare two list values using oracle?

Select main.gr_number from
(
Select st.GR_NUMBER from student st where upper(st.class_id)=upper('jtm.online137') and st.is_active_flg='Y'
and st.status='STUDYING'
and upper(st.class_days) like '%'||TO_CHAR(to_date('31-OCT-2019'),'DY')||'%'
) main
where (Select GR_NUMBER from student_class_attend where upper(class_id)=upper('jtm.online137')
and attend_date ='31-OCT-2019') not in (main.GR_NUMBER);
it is giving me error
single-row subquery returns more than one row
Looks like NOT EXISTS to me, i.e.
SELECT main.gr_number
FROM (SELECT st.GR_NUMBER
FROM student st
WHERE UPPER (st.class_id) = UPPER ('jtm.online137')
AND st.is_active_flg = 'Y'
AND st.status = 'STUDYING'
AND UPPER (st.class_days) LIKE
'%'
|| TO_CHAR (TO_DATE ('31-OCT-2019', 'dd-mon-yyyy'),
'DY')
|| '%') main
WHERE NOT EXISTS
(SELECT GR_NUMBER
FROM student_class_attend
WHERE UPPER (class_id) = UPPER ('jtm.online137')
AND attend_date = TO_DATE ('31-OCT-2019', 'dd-mon-yyyy')
AND gr_number = main.GR_NUMBER);
Note that I modified your "date" values by applying missing format mask and TO_DATE function as you shouldn't compare dates to strings. Even better: use date literal, e.g. date '2019-10-31' instead.
You can't use WHERE with a subquery that returns more than a row.
Instead of WHERE try using a left join and (for NOT IN) check for null value in left joined key:
Select main.gr_number
from (
Select st.GR_NUMBER
from student st
where upper(st.class_id)=upper('jtm.online137')
and st.is_active_flg='Y'
and st.status='STUDYING'
and upper(st.class_days) like '%'||TO_CHAR(to_date('31-OCT-2019'),'DY')||'%'
) main
LEFT JOIN (
Select GR_NUMBER
from student_class_attend
where upper(class_id)=upper('jtm.online137')
and attend_date ='31-OCT-2019'
) t ON t.GR_NUMBER main.GR_NUMBER
AND t.GR_NUMBER is null;

How to create a view from existing table records, but also adding new records that do not exist

I am trying to create a view from an existing views data, but also if there are certain lines that do not exist per part/date combo, then have those lines be created. I have the below query that is showing what I currently have for the particular s_date/part_no combos:
SELECT
s_date,
part_no,
issue_group,
s_level,
qty_filled
FROM
current_view
WHERE
part_no = 'xxxxx'
AND s_date IN (
'201802',
'201803'
)
ORDER BY
s_date,
part_no,
issue_group,
DECODE(s_level, '80', 1, '100', 2, 'Late', 3)
Which produces the below:
I know how to create a view with that data, that's the easy part. But what I'm needing is a line for each issue_group and s_level combo, and if it's a created line, to put 0 as the qty_filled.
Every part_no / s_date combo should have 6 rows that go with it
- issue_group = '1' / s_level = '80'
- issue_group = '1' / s_level = '100'
- issue_group = '1' / s_level = 'Late'
- issue_group = '2/3 ' / s_level = '80'
- issue_group = '2/3 ' / s_level = '100'
- issue_group = '2/3 ' / s_level = 'Late'
So if one of the above combinations already exists for the current s_date/part_no, then it obviously takes the qty_filled info from the current view. If not, a new line is created, and qty_filled = 0. So I'm trying to get it to look like this:
I've only shown 1 part, with a couple dates, just to get the point across. There are 10k+ parts within the table and there will never be more than 1 part/date combo for each of the 6 issue_group/s_level combos.
The idea is to generate the rows using CROSS JOIN and then bring in the extra information with a LEFT JOIN. In Oracle syntax, this looks like:
WITH v as (
SELECT v.*
FROM current_view v
WHERE part_no = 'xxxxx' AND
s_date IN ('201802', '201803')
)
SELECT d.s_date, ig.part_no, ig.issue_group, l.s_level,
COALESCE(v.qty_filled, 0) as qty_filled
FROM (SELECT DISTINCT s_date FROM v) d CROSS JOIN
(SELECT DISTINCT part_no, ISSUE_GROUP FROM v) ig CROSS JOIN
(SELECT '80' as s_level FROM DUAL UNION ALL
SELECT '100' FROM DUAL UNION ALL
SELECT 'LATE' FROM DUAL
) l LEFT JOIN
v
ON v.s_date = d.s_date AND v.part_no = ig.part_no AND
v.issue_group = ig.issue_group AND v.s_level = l.s_level
ORDER BY s_date, part_no, issue_group,
(CASE s_level WHEN '80' THEN 1 WHEN '100' THEN 2 WHEN 'Late' THEN 3 END)
One solution could be to generate a cartesian product of all expected rows using a cartesian product between the (fixed) list of values, and then LEFT JOIN it with current_view.
The following query guarantees that you will get a record for each given s_date/part_no/issue_group/s_level tuple. If no record matches in current_view, the query will display a 0 quantity.
SELECT
sd.s_date,
pn.part_no,
ig.issue_group,
sl.s_level,
COALESCE(cv.qty_filled, 0) qty_filled
FROM
(SELECT '201802' AS s_date UNION SELECT '201803') AS sd
CROSS JOIN (SELECT 'xxxxx' AS part_no) AS pn
CROSS JOIN (SELECT '1' AS issue_group UNION SELECT '2') AS ig
CROSS JOIN (SELECT '80' AS s_level UNION SELECT '100' UNION SELECT 'Late') AS sl
LEFT JOIN current_view cv
ON cv.s_date = sd.s_date
AND cv.part_no = pn.part_no
AND cv.issue_group = ig.issue_group
AND cv.s_level = ig.s_level
ORDER BY
sd.s_date,
pn.part_no,
ig.issue_group,
DECODE(sl.s_level, '80', 1, '100', 2, 'Late', 3)
NB : you did not tag your RDBMS. This should work on most of them, excepted Oracle, where you need to add FROM DUAL to each select in the queries that list the allowed values, like :
(SELECT '201802' AS s_date FROM DUAL UNION SELECT '201803' FROM DUAL) AS sd

What is the issue with this CTE WITH clause in PL SQL /Oracle?

I have below query.
The below query WITH CTE, it is returning 4 Records.
As I gave the comments, the below Select query has 55 Records and with And clause it should remove those 4 Records and return 51 records. Instead it is returning simply those 4 records only.
Just for testing I commented that AND clause and then it is functioning as expected and returning 55+4 = total of 59 Records.
How to fix this WITH CTE. What is wrong?
CREATE OR REPLACE PROCEDURE CUSTCONNECT.sp_GetPodConfigurationGridData(
p_podURL IN varchar2, --PodUrl
p_serverType IN varchar2,
p_serverName IN varchar2,
p_publishedDate IN date,
P_RECORDSET OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN P_RECORDSET FOR
--This has total of 4 Records
WITH PodServerRecords(Key, value, Overwrite, ServerName, ServerType, PublishDate ) AS (
select
PC.KeyId as Key, KeyIdValue as value, 'Pod' as Overwrite, '' as ServerName, '' as Servertype, PC.PublishDate
from (select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigLog_Tab Keylog
where Keylog.URL = p_podURL
and Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PC
where PC.RowNu = 1 and PC.IsActive = 'T'
UNION
select
PCBS.KeyId as Key, KeyIdValue as value, 'Server' as Overwrite, PCBS.ServerName, Servertype, PCBS.PublishDate
from (select
Serlog.*, PS.ServerType, row_number() over (partition by Serlog.KeyId order by Serlog.PublishDate desc) as RowNu
from PodConfigByServerLog_Tab Serlog
join PodServer_tab PS on PS.ServerName = Serlog.ServerName
and Serlog.URL = PS.URL
where Serlog.URL = p_podURL
and Serlog.ServerName = p_serverName
and Serlog.PublishDate >= p_publishedDate and Serlog.PublishDate <= sysdate
) PCBS
where PCBS.RowNu = 1 and PCBS.IsActive = 'T'
)
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
)
UNION
--This is total of 4 Records
SELECT
Key, value, Overwrite, ServerName, ServerType, PublishDate
FROM PodServerRecords
Order By Key;
END;
/
Your problem is that the CTE does not have a column called KeyId. You renamed it to Key. However, NOT IN has unexpected behavior when there are NULL values. You can fix this by eliminating them directly:
PCK.KeyId not in (
select psr.KeyId
from PodServerRecords psr
where psr.KeyId IS NOT NULL
)
I recommend using NOT EXISTS instead:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.KeyId = PCK.KeyId
)
This may fix your problem.
Actually, I don't see a KeyId in your CTE. So, I think you want:
NOT EXISTS (select 1
from PodServerRecords psr
where psr.Key = PCK.KeyId
)
Note the preceding statements will return errors, indicating that the problem is the misnamed column.
I think you should remove that UNION part of your query cause it's readding those 4 records from PodServerRecords. Your query should rather be
--This has total of 55 Records
select
PCK.KeyId as Key ,DefaultKeyIdValue as value,'Default' as Overwrite, '' as ServerName, '' as Servertype, PCK.PublishDate
from
(select
Keylog.*, row_number() over (partition by Keylog.KeyId order by Keylog.PublishDate desc) as RowNu
from PodConfigKeyLog_Tab Keylog
where Keylog.PublishDate >= p_publishedDate and Keylog.PublishDate <= sysdate
) PCK
join POD_TAB PS on PS.URL = p_podURL
where PCK.RowNu = 1 and PCK.IsActive = 'T'
--This And caluse should remove those 4 Records and total Records should be 51.
and PCK.KeyId not in (
select KeyId
from PodServerRecords
);

Need to get the column from the table in exists clause

I have a query below:
SELECT AIDI.LOAN_NUM, AIDI.LOCATION_CODE, AIDI.ORD_NUM, AIDI.MTN, AIDI.LOAN_STATUS, COUNT(*)
FROM table1 AIDI
WHERE AIDI.LOAN_STATUS = 'A'
AND EXISTS (SELECT 1 FROM ORDERS AO
WHERE AO.ACE_ORD_NUM = AIDI.ORD_NUM
AND AO.ACE_ORD_COMPLETION_TIME >= TRUNC(SYSDATE -1)
AND AO.ACE_ORD_COMPLETION_TIME < TRUNC(SYSDATE))
GROUP BY AIDI.LOAN_NUM, AIDI.LOCATION_CODE, AIDI.ORD_NUM, AIDI.MTN, AIDI.LOAN_STATUS
HAVING COUNT(*) > 1;
I need to get the AO.ACE_ORD_COMPLETION_TIME this column into select clause so that i can see the date also in the result set.