Subquery with invalid identifier error in sql - sql

want to select tour date and site names in advance of total cost is more than 230 and that tour has more than 7 persons. the complete code is below, the first part of union works.
SELECT tour_date AS "Departure Date", site_name "Site Name"
FROM partres, reservation, tour, site
WHERE partres.res_id = reservation.res_id
AND reservation.tour_id = tour.tour_id
AND tour.site_id = site.site_id
GROUP BY tour_date, site_name
HAVING COUNT(part_id) > 7
UNION
SELECT tour_date AS "Departure Date", site_name "Site Name"
FROM (
SELECT res_id,tour_date,site_name, (res_partcost +NVL(RES_GEARCOST,0)) as "total_cost"
FROM reservation,site,tour)
WHERE reservation.tour_id = tour.tour_id
AND tour.site_id = site.site_id
AND total_cost > 230
GROUP BY tour_date, site_name;
I still got errors as
ORA-00904: "TOTAL_COST": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 437 Column: 7
Thanks

You need to move your join conditions inside the subquery
SELECT tour_date AS "Departure Date", site_name "Site Name"
FROM (
SELECT res_id,tour_date,site_name, (res_partcost +NVL(RES_GEARCOST,0)) as "total_cost"
FROM reservation,site,tour
WHERE reservation.tour_id = tour.tour_id
AND tour.site_id = site.site_id ) Res1
WHERE Res1.total_cost > 230 // this will not be displayed in a result
GROUP BY tour_date, site_name;

A union is not going to give you an "and" between the conditions. It is going to give you an "or" (because anything that matches either condition will be included).
I think you should phrase this as a single query, with subqueries. Also, proper join syntax is a benefit:
SELECT tour_date AS "Departure Date", site_name "Site Name"
FROM partres p join
reservation r
on p.res_id = r.res_id join
tour t
on r.tour_id = t.tour_id and
(res_partcost + coalesce(RES_GEARCOST,0)) > 230 join
site s
on t.site_id = s.site_id
GROUP BY tour_date, site_name
having COUNT(part_id) > 7;
This version is making a guess that total_cost is in the reservation table.

Related

Multiple Sub Queries with Multiple JOINS Oracle

I have a large ORACLE SQL file with multi joins and multiple sub queries. I am having issues joining two of the sub queries. I have tried many different methods but the closest that I have gotten is below. The piece that is giving me trouble is the first portion of the join with the multiple subqueries (the Address Eff Date and the Employee Eff Date. The error message that I am receiving is ORA-00907: missing right parenthesis 00907. 00000 - "missing right parenthesis". I can't find where the right parenthesis is missing and I suspect it is more than that or some other type of syntax issue. The two tables that I have had trouble joinging are the EMPLOYEE_EFF_DATE table and the ADDRESS_EFF_DATE table. Both of these tables have an EFF_DATE field, and for both tables I need to pull the record with the most recent effective date (by SSN field). I believe I have accounted for that with the ROW_NUMBER() OVER (PARTITION method but if there is a more efficient or easier way to to this I am absolutely open to suggestions.
/*Subscriber Code*/
eed.P_COMPANY_ID_I as "Client Company ID"
,cs.REAL_SSN as "Employee SSN"
,cs.REAL_SSN as "Member SSN"
,'Subscriber' as "Person Type"
,eed.LAST_NAME as "Last Name"
,eed.FIRST_NAME as "First Name"
,eed.BIRTHDATE as "Date of Birth"
,eed.SEX as "Gender"
,aed.Address_1 as "Address 1"
,aed.Address_2 as "Address 2"
,aed.City
,aed.State
,aed.Zip
,aed.Country as "Country Code"
,aed.Telephone as "Employee Home Phone"
,eed.EMAIL_ADDRESS as "Employee Email Address"
,CASE
WHEN eed.controlled_group_status = 'L'
OR eed.controlled_group_status = 'P'
then eed.EFF_DATE
ELSE NULL
END
as "Date Last Actively At Work"
/*Remove line below*/
,eed.CONTROLLED_GROUP_STATUS
,CASE
WHEN eed.controlled_group_status = 'L'
OR eed.controlled_group_status = 'P'
then 'LEAVE'
ELSE NULL
END
as "Leave Status"
,CASE
WHEN eed.controlled_group_status = 'L'
OR eed.controlled_group_status = 'P'
then eed.EFF_DATE + 1
ELSE NULL
END
as "Leave Begin Date"
,eed.LATEST_HIRE_DATE as "Employee Date of Hire"
,eed.LAST_TERM_DATE as "Employee Date of Termination"
,mcemd.RATE_1 as "Employee Salary"
,ele.LIFE_EVENT_ID as "Life Event ID"
,ele.LIFE_EVENT_DATE as "Loss of Coverage Date"
FROM
/*Employee_Eff_Date*/
(SELECT *
FROM
(SELECT *
FROM
(SELECT eed1.*,
ROW_NUMBER() OVER (PARTITION BY eed1.SSN ORDER BY EFF_DATE DESC) as seqnum
FROM EMPLOYEE_EFF_DATE eed1)
WHERE seqnum = 1) eed)
JOIN
/*Address_Eff_Date*/
(SELECT *
FROM
(SELECT *
FROM
(SELECT aed1.*,
ROW_NUMBER() OVER (PARTITION BY aed1.SSN ORDER BY EFF_DATE DESC) as seqnum
FROM ADDRESS_EFF_DATE aed1
) aed1
ON aed1.SSN = eed.SSN
WHERE aed1.seqnum = 1) aed)
INNER JOIN COMPANY_EMPLOYMENT_DATA ced
ON eed.SSN = ced.SSN
INNER JOIN MV_COMB_EMP_MAX_DTS mcemd
ON eed.SSN = mcemd.SSN
INNER JOIN EMPLOYEE_LIFE_EVENTS ele
ON ele.SSN = eed.SSN
WHERE eed.P_COMPANY_ID_I = 1234
/*Address_Eff_Date qualifying statement*/
AND aed.ADDRESS_KEY = 0
/*EMPLOYEE_LIFE_EVENTS qualifying statement*/
/*Below line indicates the Life Event Dates (set to the past week)*/
AND ele.LIFE_EVENT_DATE >= sysdate-7
AND ele.LIFE_EVENT_DATE <= sysdate
I think you actually want this. Note you have more level of query nesting than you actually need and I have removed the extra ones:
/*Employee_Eff_Date*/
(SELECT *
FROM
(SELECT eed1.*,
ROW_NUMBER() OVER (PARTITION BY eed1.SSN ORDER BY EFF_DATE DESC) as seqnum
FROM EMPLOYEE_EFF_DATE eed1) eed1
WHERE seqnum = 1) eed
JOIN
/*Address_Eff_Date*/
(SELECT *
FROM
(SELECT aed1.*,
ROW_NUMBER() OVER (PARTITION BY aed1.SSN ORDER BY EFF_DATE DESC) as seqnum
FROM ADDRESS_EFF_DATE aed1
) aed1
WHERE aed1.seqnum = 1) aed ON aed.SSN = eed.SSN

Trying to make a single query out of these 2 queries

I am trying to get the percentage of calls that fit the allowed time-frame to get answered. But due to one condition, having the call less than 30 seconds, I am having an issue getting it to work. I tried working out the 30 seconds condition in the Select statement but it did not work ( I kept getting 100% every time and after looking at the numbers individually, it was not possible.
Select date, count("speed of answer" < '00:00:30')/ count(calls) as SLA
From five9_data.calllog
Where "call type" = 'Inbound' and campaign in ('Eves Addiction', 'Brook and York') and "service level" = '1' and skill = 'Eves Sales V'
Group By date
Order By date desc
Limit 5000
Here are the 2 queries in full:
Select date, count(calls) as Total
From five9_data.calllog
Where
"call type" = 'Inbound'
and campaign in ('Eves Addiction', 'Brook and York')
and "service level" = '1'
and skill = 'Eves Sales V'
Group By date
Order By date desc
AND
Select date, count("speed of answer") as AnsweredInTime
From five9_data.calllog
Where
"call type" = 'Inbound'
and campaign in ('Eves Addiction', 'Brook and York')
and "service level" = '1'
and skill = 'Eves Sales V'
and "speed of answer" < '00:00:30'
Group By date
Order By date desc
It has the same data source so union did not work, and did not think Join would work.
End game I want to be able to make a query that allows the 2 queries above to work and finally divide AnsweredInTime by Total.
I would recommend writing the query as:
Select date,
count(*) as total_count,
sum( ("speed of answer" < '00:00:30')::int ) as num_AnsweredInTime,
avg( ("speed of answer" < '00:00:30')::int ) as ratio_AnsweredInTime
from five9_data.calllog
where "call type" = 'Inbound' and
campaign in ('Eves Addiction', 'Brook and York') and
"service level" = '1' and
skill = 'Eves Sales V'
Group By date
Order By date desc
The COUNT(exp) function will count the number of rows for which exp is not null -- it doesn't care about true or false. You can verify this by executing the command select count(false) (evaluates to 1) and select count(NULL) (evaluates to 0). So instead of
count("speed of answer" < '00:00:30')
you could try either
count(nullif("speed of answer" < '00:00:30', FALSE))
(if speed is < 00:30 this will NOT be null, and thus will be counted) or
sum(case when "speed of answer" < '00:00:30' then 1 else 0 end)
Select date,
count(*) as total_count,
sum( ("speed of answer" < '00:00:30')::int ) as num_AnsweredInTime,
avg( ("speed of answer" < '00:00:30')::int ) as ratio_AnsweredInTime
from five9_data.calllog
where "call type" = 'Inbound' and
campaign in ('Eves Addiction', 'Brook and York') and
"service level" = '1' and
skill = 'Eves Sales V'
Group By date
Order By date desc

SELECT item, date WHERE date < sysdate - 60

Here's my sql script. I'm trying to pull all items that haven't been invoiced in 60 days. It's only returning one line. Any idea why? Thanks for your help!
SELECT oel.ordered_item Part_No,
MAX(rca.trx_date) AS "Last Invoice Date"
FROM oe_order_lines_all oel,
ra_customer_trx_all rca
WHERE rca.trx_date < trunc(sysdate)-60
GROUP BY oel.ordered_item
You should add condition for this line for ',', which is inner join here,
SELECT oel.ordered_item Part_No,
MAX(rca.trx_date) AS "Last Invoice Date"
FROM oe_order_lines_all oel,
ra_customer_trx_all rca
WHERE rca.trx_date < trunc(sysdate)-60 --------shoud be a condition connects rca and oel
GROUP BY oel.ordered_item
I don't know why only one row is returned. But you are missing join conditions. This would be obvious if you used proper JOIN syntax.
Based on your description, the logic you want is more like this:
SELECT oel.ordered_item as Part_No,
MAX(rca.trx_date) AS "Last Invoice Date"
FROM oe_order_lines_all oel LEFT JOIN
ra_customer_trx_all rca
ON oel.?? = rca.??
GROUP BY oel.ordered_item
HAVING MAX(rca.trx_date) < trunc(sysdate) - 60 OR MAX(rca.trx_date) IS NULL;
The ?? is for the columns used for joining the tables.

Invalid Number with date filter in Oracle SQL where clause

Using Oracle SQL, I am getting this error with my query:
ORA-01722: invalid number
01722. 00000 - "invalid number"
I am using two tables to get a maximum date and min date from a transaction table for requests. Without the line "AND mgr_min.create_date > to_date('01-01-15', 'MM-DD-YY')" it seems to return the results I need. But when I try to filter based on date that a request was created...I get the error. Here is the query:
SELECT mr.accessor_id,
mrs.status_description,
mso.option_name,
CAST(mgr_max.create_date AS TIMESTAMP) AS "Action Date",
mgr_max.detail_comment AS "Comment",
mgr_min.create_date AS "Date Created"
FROM moca_request mr,
moca_request_status mrs,
moca_system_option mso,
moca_system ms,
(SELECT mrt.request_id, mrt.status_id, mrt.approver_id, mrt.create_date, mrt.detail_comment
FROM moca_request_transaction mrt
INNER JOIN (
SELECT request_id, MAX(create_date) AS maxdate
FROM moca_request_transaction
GROUP BY request_id) mrt2
ON mrt.request_id = mrt2.request_id AND mrt.create_date = mrt2.maxdate) mgr_max,
(SELECT mrt3.create_date, mrt3.request_id
FROM moca_request_transaction mrt3
INNER JOIN (
SELECT request_id, MIN(create_date) AS createdate
FROM moca_request_transaction
GROUP BY request_id) mrt4
ON mrt3.request_id = mrt4.request_id AND mrt3.create_date = mrt4.createdate) mgr_min
WHERE mgr_max.request_id = mr.request_id
AND mgr_max.status_id = mrs.status_id
AND mgr_min.request_id = mr.request_id
AND mso.option_id = mr.option_id
AND ms.system_id = mr.system_id
AND mgr_min.create_date > to_date('01-01-15', 'MM-DD-YY')

Query on how to select data based on single condition

Need your help to review the below request.
i am using the below query and what i want to achieve is as below
i am trying to extract the min value of the new_status_id and not fetch any other details of any other status at all. Basically i am getting more than one line as output for one v_id that i input where as the desired output is one line and min(timestamp) to get fetched under column name Upload as defined below
Select
to_char(to_date(date,'DY Mon DD YYYY'),'MM-DD')||' '||Away_team.name||' '||'#'||' '||home_team.name as "Title",
video_jobs.id as "Job Id",
markets.name as "Market",
round as "Round",
to_char(to_date(date,'DY Mon DD YYYY'),'DD-Mon-YY') as "Date Aired",
competitions.name as "Competition",
Home_team.name as "Home Team",
Away_team.name as "Away Team",
job_statuses.name as "Job Status",
networks.name as "Network",
stadiums.name as "Stadium",
Round(images_count/3600.0,2) as "Footage Hours",
round(sum(minutes_in_logo_finder)/60.0,2) as "Logo Picker Time",
Round(sum(minutes_in_hits_editor)/60.0,2) as "Hits Editing Time",
Round(sum(minutes_in_branding)/60.0,2) as "Branding Time",
Round(sum(minutes_in_tagging)/60.0,2) as "Tagging Time",
Round(sum(minutes_in_qc)/60.0,2)as "QC Time",
Round(sum(minutes_in_idle)/60.0,2) as "Idle Time",
Round(sum(loading_time)/60.0,2) as "Loading Time",
Round(sum(minutes_in_logo_finder+minutes_in_hits_editor + minutes_in_branding +minutes_in_tagging +minutes_in_qc+minutes_in_idle+loading_time)/60.0,2) as "Total"
from video_jobs
Join markets on video_jobs.market_id = markets.id
Join stadiums on video_jobs.stadium_id = Stadiums.id
Join job_statuses on video_jobs.status_id = job_statuses.id
Join competitions on video_jobs.competition_id = competitions.id
Join networks on video_jobs.network_id = networks.id
Join sessions on video_jobs.id = sessions.job_id
join teams as Home_team on video_jobs.home_team_id = home_team.id
join teams as Away_team on video_jobs.away_team_id = Away_team.id
Join video_job_status_history on video_jobs.id = video_job_status_history.video_job_id
Where video_jobs.id > 163026
group by
video_jobs.id,
markets.name,
video_jobs.round,
stadiums.name,
job_statuses.name,
competitions.name,
networks.name,
video_jobs.images_count,
home_team.name,
Away_team.name,
video_jobs.date
order by
video_jobs.id
Add the condition into the where clause:
select min(timestamp) as "Uplaod"
from v_jobs
where v_id = 1234 and new_status_id = 25;
EDIT:
In that case, what you want is conditional aggregation:
select min(case when new_status_id = 25 then timestamp end) as MinTimestamp25
. . .