Oracle query getting ORA-00907: missing right parenthesis - oracle

I've read through the other missing right parenthesis questions and haven't found an answer to my problem. I assume it is a syntax error cutting things off before the end (I'm not really an Oracle guy) but I don't know where it is. The query is supposed to pull the customer ID and the latest year there is a record for that customer. The parameters are a customer ID number (unique by district but different from the organizational one), the district, and the year being searched. If there is no record for the searched year for that district, no records should be returned.
SELECT DISTINCT CUSTOMER.CUSTOMER_ID_ALT, tblMaxYear.maxYear
FROM CUSTOMER CROSS JOIN
(SELECT to_char(Max(tblYr.FISCAL_YEAR), 'YYYY') AS maxYear
FROM CUSTOMER AS tblYr
WHERE tblYr.DISTRICT_KEY= :district
AND tblYr.CUSTOMER_ID= :cust) tblMaxYear
WHERE CUSTOMER.DISTRICT_KEY=:district
AND CUSTOMER.CUSTOMER_ID= :cust
AND to_char(CUSTOMER.FISCAL_YEAR, 'YYYY') = :prmYear

Remove the AS in:
FROM CUSTOMER AS tblYr
AS can be used for column aliasing, not table aliasing

Related

How to find the sum of each group which is grouped by another group?

I am actually trying to make a matrix table using Oracle Analytics tool and PL/SQL.
Let's say i have a query which has in select statement variables Employee, Description, orderid ,amount and is grouped by Employee, Description. Orderid and amount belong to the same group. From this query i want extract the sum of the amount of each description from all employees. Do you have any idea how i can do this?
Thank you.
Edit:
Let's say we have the following query:
Select Employee, Description, orderid ,amount
From Employees
Group by Employee,Description
I want to extract the sum of amount from each Description group but from all Employees.A way to do this could be like this:
Select Description,sum(amount)
From Employees
Group by Description
But the actual query is much more complex and if i choose to make another query for finding the sum of each description i have to link it somehow to the first query to be able to show the results at the report.
Do you have any idea of a way to do this through oracle analytics publisher?
Thank you.
Select coalesce(Employee,'ALL_EMPOYEES'), coalesce(Description,'ALL_DESCRIPTION'), orderid ,amount
From Employees
Group by ROLLUP (Employee,Description)
Select coalesce(Employee,'ALL_EMPOYEES'), coalesce(Description,'ALL_DESCRIPTION'), orderid ,amount
From Employees
Group by CUBE (Employee,Description)

COLUMN AMBIGUOUSLY DEFINED ORACLE

im getting an column ambiguously defined im trying to write a query to get data from three different tables my query is
select flight_no,
country_code,
destination,
depatue_time,
arrival_time
from flight,
country,
flight_availibility
where country_code='MCT'
and destination='IND'
order by flight_no;
and im getting error can anybody tell me what is wrong!!!
The error is telling you that you're asking for a column that shares a name from more than one of those tables. You want 'flight_no' - but, there may be a column named 'flight_no' in both the flight and country tables.
To avoid this, use aliases in your FROM clause.
Example
select a.col1, b.col1
from table1 a, table2 b
where a.id = b.id;
This isn't ambiguous, because you're explicitly telling Oracle which columns named 'col1' you want - you're not making it guess.
This isn't part of your question, but your query as you write it will cause the database to join every record in each table to every other record in the other two tables. This is known as a Cartesian Join or Product.
Is it necessarily wrong? Maybe not. But 99% of the time, it's not what you want. You only want the rows that 'match' - so use a WHERE clause and filter out the rows.
Or go the ANSI JOIN way and do it in the FROM clause.
The error occurred because same column name having in the 2 tables , so when we run the query using only column name , this error is occurring
Try the below to avoid those issue :
select a.flight_no,b.country_code,a.destination,c.depature_time,c.arrival_time
from
flight a ,
country b

How to query for Inactive Employees using BI Publisher in Oracle Fusion?

I'm new to BI Publisher and I'm using it through Oracle Fusion Applications.
I am trying to make a report relating to the Inactive Employees in an organization. However I am unable to figure out how to query for an inactive or terminated employee.
I initially used this query:
SELECT PERSON_ID, PERSON_NUMBER, EFFECTIVE_START_DATE, EFFECTIVE_END_DATE
FROM PER_ALL_PEOPLE_F
WHERE TRUNC(SYSDATE) NOT BETWEEN TRUNC(EFFECTIVE_START_DATE) AND TRUNC(EFFECTIVE_END_DATE)
My other considerations were attributes from the PER_ALL_ASSIGNMENTS_M table including PRIMARY_WORK_RELATION_FLAG, PRIMARY_ASSIGNMENT_FLAG and ASSIGNMENT_TYPE considering that the employee's assignment details would help somehow. However I was unsuccessful.
I wanted to know if there was any other proper way to query for inactive employees. Is there any particular attribute in any table which would tell me for certain that an employee is active or terminated? When an employee is terminated in Oracle Fusion, which all table attributes get affected?
Thank you for your help.
The easiest way to do this is simply :
SELECT * FROM YourTable t
WHERE TRUNC(t.END_DATE) <= trunc(sysdate)
Some times there is also an indication column like IS_ACTIVE or something. You can also consider adding it, and simply updating it to 1 for all the records returned from the above query.
Other then that, we can't really help you. We don't know your table structures, we don't know what data you store in them and which column indicates what .
I have found what i was looking for. ASSIGNMENT_STATUS_TYPE='INACTIVE' was what I needed (As mentioned in the question, this solution is without considering 'EFFECTIVE_END_DATE') Getting the 'latest' assignment status of an employee was what I needed to find. The following query works if the employee has only one Assignment assigned.
SELECT PAPF.PERSON_ID, PAPF.PERSON_NUMBER
FROM PER_ALL_PEOPLE_F PAPF, PER_ALL_ASSIGNMENTS_M PAAM
WHERE 1=1
AND TRUNC(PAAM.EFFECTIVE_START_DATE) = (SELECT MAX(TRUNC(PAAM_INNER.EFFECTIVE_START_DATE))
FROM PER_ALL_ASSIGNMENTS_M PAAM_INNER
WHERE PAAM_INNER.PERSON_ID=PAAM.PERSON_ID
GROUP BY PAAM_INNER.PERSON_ID)
AND PAPF.PERSON_ID=PAAM.PERSON_ID
AND PAAM.PRIMARY_FLAG='Y'
AND PAAM.ASSIGNMENT_STATUS_TYPE='INACTIVE'
AND TRUNC(SYSDATE) BETWEEN PAAM.EFFECTIVE_START_DATE AND PAAM.EFFECTIVE_END_DATE
AND TRUNC(SYSDATE) BETWEEN PAPF.EFFECTIVE_START_DATE AND PAPF.EFFECTIVE_END_DATE
ORDER BY 1 ASC
I had help from the Oracle Support Community to get to an answer.
Link: https://community.oracle.com/message/14000136#14000136
However in a case where an employee was given an assignment say starting from year 2000 and ending at 20015, then another assignment starting from 2016 till present, the above query will return one record of the said employee as 'Inactive' if the Max Effective_start_date condition is not checked. (Since one became Inactive on 2015), even though her current Assignment status is 'Active' and she is currently not terminated.
In such a case, it is wise to retrieve the record with the greatest 'EFFECTIVE_START_DATE' from the PER_ALL_ASSIGNMENTS_M table, ie, checking if EFFECTIVE_START_DATE = MAX(EFFECTIVE_START_DATE)

Adding today's date to Oracle query results when using wildcard *

this might be a lack of very basic knowledge, but I just can't figure it out. Searching for the answer and trial and error haven't helped much.
Returning all recordsets from a table (SELECT * FROM X) --> no problem.
Returning today's date (SELECT TO_CHAR(SYSDATE, 'DD-MM-YYYY') FROM DUAL) --> no problem.
Returning all recordsets from the same table as well as today's date --> no luck. I have tried subselects, union, joins, with-statements, ... it's driving me nuts.
When I name the columns I want returned (SELECT Columname1, Columnname2, to_char(sysdate....)) it works. This problems seems to only occur when using wildcards.
How do I get Oracle to return "all columns", today's date"?
Thanks!
You have to prefix the wildcard with the table name (or alias, if you've used one):
SELECT X.*, TO_CHAR(SYSDATE, 'DD-MM-YYYY') AS TODAYS_DATE FROM X
Using the wildcard is generally not considered a good idea, as you have no control over the order the columns are listed (if the table was built differently in different environments) and anyone consuming this output may be thrown if the table definition changes in the future, e.g. by adding another column. It's better to list all the columns individually.

ORA-00979 not a Group By function error

Iam trying to select 2 values from a Table, Employee emp_name, emp_location grouping by emp_location, iam aware that the columns which are in group by function needs to be in select clause, but i would like to know whether is there any other way to get these value in a single query.
My intention is to select only one employee per location based on age.
sample query
select emp_name,emp_location
from Employee
where emp_age=25
group by emp_location
please help in this regard.
Thanks a lot for all the guys who have responded for this question. I will try to learn these windows functions as these are very handy.
The reason why this works in MySQL and not in Oracle, is because in Oracle, as well most other databases, you either need to specify a field (or expression) in the group by clause, or it has to be an aggregation which combines the values of all values in the group into a single one. For instance, this would work:
select max(emp_name),emp_location
from Employee
where emp_age=25
group by emp_location
However, it's may not the best solution. It will work if you want just the name, but you'll get into trouble when you want to have multiple fields for an employee. In that case max won't do the trick. In the query below, you might get a first name that doesn't match the last name.
select max(emp_firstname), max(emp_lastname), emp_location
from Employee
where emp_age=25
group by emp_location
On solution for this, is using a window function (analytical function). With those, you can generate a value for each record, without immediately reducing the number of records. For instance, with a windowed max function, you could select the max age for people named John, and display that value next to every John in the result, even if they don't have that age.
Some functions, like rank, dense_rank and row_number can be used to generate a number for each employee, which you can then use to filter by. In the example below, I created such a counter per location (partition by), and ordered by, in this case name and id. You can specify other fields as well, for instance if you want one name per age per location, you specify both age and location in partition by. If you want the oldest employee of each location, you can remove where emp_age=25 and order by emp_age desc instead.
select
*
from
(select
emp_name, emp_location,
dense_rank() over (partition by emp_location order by emp_name, emp_id) as emp_rank
from Employee
where emp_age=25)
where
emp_rank = 1
ORA-00979 not a Group By function error
Only aggregate functions and columns specified in the GROUP BY clause are allowed in the SELECT clause.
In that regard, Oracle follows the SQL standard closely. But, as you noticed in your comment, some other RDBMS are less strict than Oracle regarding that point. For example, to quote MySQL's documentation (emphasis mine):
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. [...]
However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
So, in the recommended use case, adding the extra columns to the GROUP BY clause will lead to the same result.
select emp_name,emp_location
-- ^^^^^^^^
-- this is *not* part of the ̀`GROUP BY` clause
from Employee
where emp_state=25
group by emp_location
Maybe are you looking for:
...
group by emp_location, emp_name
select emp_name,emp_location
from Employee
where emp_age=25
group by emp_name,emp_location
or
select max(emp_name) emp_name,emp_location
from Employee
where emp_age=25
group by emp_location

Resources