I need help creating a table using the pivot clause to include the average salary of each Division_ID and use Division_ID as a Row and Job_ID as Column using data in employees2 table.
Here is my query
SELECT *
FROM (
SELECT JOB_ID, DIVISION_ID, SALARY
FROM employees2
WHERE DIVISION_ID IN (1, 2, 3, 4, 5)
)
PIVOT (
AVG(SALARY) FOR JOB_ID IN (1 AS ENG, 2 AS MGR, 3 AS PRE, 4 AS WOR, 5 AS TEC)
)
ORDER BY DIVISION _ID;
I get the following error when I try to execute the statement
ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
*Cause:
*Action:
Error at Line: 6 Column: 3
Here is the data that is in employees2 table (note their are only 5 JOB_IDs)
Finally, here is an example of how my result should look like
Given your sample data, your query is checking for int division_ids and job_ids, when it appears those are varchar fields.
Here is a working version:
SELECT *
FROM (
SELECT JOB_ID, DIVISION_ID, SALARY
FROM employees2
WHERE DIVISION_ID IN ('div1','div2')
)
PIVOT (
AVG(SALARY) FOR JOB_ID IN ('job1', 'job2')
)
ORDER BY 1
SQL Fiddle Demo
Related
This question already has answers here:
Using an Alias in a WHERE clause
(5 answers)
Closed 8 months ago.
I am only a beginner in SQL, but I've come across this annoying error. SQL is having an issue with the WHERE clause of this script:
SELECT
ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY,
(ITEM_PRICE*QUANTITY) AS price_total,
(DISCOUNT_AMOUNT*QUANTITY) AS discount_total,
((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total
FROM ORDER_ITEMS
WHERE item_total > 500
ORDER BY item_total;
I am receiving this error:
Error starting at line : 1 in command -
SELECT
ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY,
(ITEM_PRICE*QUANTITY) AS price_total,
(DISCOUNT_AMOUNT*QUANTITY) AS discount_total,
((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total
FROM ORDER_ITEMS
WHERE item_total > 500
ORDER BY item_total DESC;
Error at Command Line : 7 Column : 7
Error report -
SQL Error: ORA-00904: "ITEM_TOTAL": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
I have no idea why it has no issue with price_total nor discount_total, but is reporting item_total as invalid. I am trying to first select only the items which have a total greater than 500 when the discount amount is subtracted and it is multiplied by the quantity. Then, I need to sort the results in descending order by item_total
An alias can be used in a query select list to give a column a different name. You can use the alias in GROUP BY, ORDER BY, or HAVING
clauses to refer to the column.
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is
evaluated, the column value may not yet have been determined.
So, the following query is illegal:
SQL> SELECT empno AS employee, deptno AS department, sal AS salary
2 FROM emp
3 WHERE employee = 7369;
WHERE employee = 7369
*
ERROR at line 3:
ORA-00904: "EMPLOYEE": invalid identifier
SQL>
The column alias is allowed in:
GROUP BY
ORDER BY
HAVING
You could refer to the column alias in WHERE clause in the following cases:
Sub-query
Common Table Expression(CTE)
For example,
SQL> SELECT * FROM
2 (
3 SELECT empno AS employee, deptno AS department, sal AS salary
4 FROM emp
5 )
6 WHERE employee = 7369;
EMPLOYEE DEPARTMENT SALARY
---------- ---------- ----------
7369 20 800
SQL> WITH DATA AS(
2 SELECT empno AS employee, deptno AS department, sal AS salary
3 FROM emp
4 )
5 SELECT * FROM DATA
6 WHERE employee = 7369;
EMPLOYEE DEPARTMENT SALARY
---------- ---------- ----------
7369 20 800
SQL>
Starting from Oracle 12c you could use CROSS APPLY to define expression and then you could refer to them in WHERE clause:
SELECT
o.ITEM_ID, o.ITEM_PRICE, o.DISCOUNT_AMOUNT, o.QUANTITY,
s.price_total, s.discount_total, s.item_total
FROM ORDER_ITEMS o
CROSS APPLY (SELECT ITEM_PRICE*QUANTITY AS price_total,
DISCOUNT_AMOUNT*QUANTITY AS discount_total,
(ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY AS item_total FROM dual) s
WHERE s.item_total > 500
ORDER BY s.item_total;
You cannot use the column name which is used as alias one in the query
Reason:
The query will first checks for runtime at that time the column name "item_total" is not found in the table "ORDER_ITEMS" because it was give as alias which is not stored in anywhere and you are assigning that column in desired output only
Alternate:
If you want to use that type go with sub queries it's performance is not good but it is one of the alternate way
SELECT * FROM
(SELECT
ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY,
(ITEM_PRICE*QUANTITY) AS price_total,
(DISCOUNT_AMOUNT*QUANTITY) AS discount_total,
((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total
FROM ORDER_ITEMS) as tbl
WHERE tbl.item_total > 500
ORDER BY tbl.item_total;
I have following query
SELECT ACTIONFINANCIALTRANSACTIONLOG.ID_CSE,
ACTIONFINANCIALTRANSACTIONLOG.DTE_PROC
FROM CSESDEV02.FINANCIAL_TRAN_LOG ACTIONFINANCIALTRANSACTIONLOG
GROUP BY ACTIONFINANCIALTRANSACTIONLOG.ID_CSE
HAVING COUNT(TXT_DESC) > 9
this results in
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action: Error at Line: 57 Column: 47
however, if i select only 1 column , it works
SELECT ACTIONFINANCIALTRANSACTIONLOG.ID_CSE
FROM CSESDEV02.FINANCIAL_TRAN_LOG ACTIONFINANCIALTRANSACTIONLOG
GROUP BY ACTIONFINANCIALTRANSACTIONLOG.ID_CSE
HAVING COUNT(TXT_DESC) > 9
why is that?
Although there's no aggregate function in SELECT column list, all columns that aren't aggregated should be part of the group by clause.
If there are 2 columns you're selecting, both have to be part of the group by.
BTW, table alias should be short so that it "simplifies" query and makes it easier to read. You did the opposite.
This is what works OK - only one column in select and it is part of group by:
SQL> select deptno
2 from emp
3 group by deptno
4 having count(job) > 1;
DEPTNO
----------
30
20
10
This doesn't work: two columns in select list, only one in group by:
SQL> select deptno,
2 ename
3 from emp
4 group by deptno
5 having count(job) > 1;
ename
*
ERROR at line 2:
ORA-00979: not a GROUP BY expression
But, when they both are in group by, query is OK:
SQL> select deptno,
2 ename
3 from emp
4 group by deptno, ename
5 having count(job) > 1;
no rows selected
SQL>
Read documentation.
Gist:
SelectItems in the SelectExpression with a GROUP BY clause must
contain only aggregates or grouping columns.
This is happening because GROUP by require all the column defined in SELECT clause.
The SELECT statement used in the GROUP BY clause can only be used contain column names, aggregate functions, constants and expressions.
select count(1),deptno
from emp
group by deptno
having count(1) > 1;
ACTIONFINANCIALTRANSACTIONLOG.DTE_PROC is not the product of a summary function and is not mentioned in the GROUP_BY clause so you get the error you've gotten. Perhaps you could use:
SELECT ftl.ID_CSE,
ftl.DTE_PROC
FROM (SELECT af.ID_CSE,
COUNT(af.TXT_DESC) AS TXT_DESC_COUNT
FROM CSESDEV02.FINANCIAL_TRAN_LOG af
GROUP BY af.ID_CSE
WHERE COUNT(af.TXT_DESC) > 9) iq
INNER JOIN CSESDEV02.FINANCIAL_TRAN_LOG ftl
ON ftl.ID_CSE = iq.ID_CSE
Syntax aside, think about the aggregation group you are defining with your group by clause:
GROUP BY ID_CSE
means you want one row per ID_CSE. Examples would be average salary per department, total sales per region, vaccinations per country.
In that one row for each id_cse, what dte_proc should be displayed if there is more than one distinct value?
For example, say your data contains
ID_CSE DTE_PROC
------ ----------
1 X
1 Y
2 Z
Now if you query
select id_cse, date_proc, count(*) from financial_tran_log
group by id_cse
what results do you expect to see?
ID_CSE DTE_PROC COUNT(*)
------ -------- --------
1 ??? 2
2 Z 1
It can't be done, hence the syntax error.
I have the following SQL schema:
Create table Employee (Id int, Salary int);
Truncate table Employee;
insert into Employee (Id, Salary) values ('1', '100');
insert into Employee (Id, Salary) values ('2', '200');
insert into Employee (Id, Salary) values ('3', '300');
And executing following query against database:
SELECT Salary as SecondHighestSalary
FROM Employee
ORDER BY Salary
OFFSET 1 ROWS FETCH FIRST 1 ROWS ONLY;
It works on Oracle XE 18but on leetcode.com (which version of Oracle they run I don't know) it returns following error:
ORA-00933: SQL command not properly ended
What am I doing wrong?
Error message indicates that you are using version lower than Oracle 12c(most likely Oracle 11g XE).
OFFSET FETCH was introduced in version 12c. You could easily check it by executing:
select * from V$VERSION;
SELECT Salary as SecondHighestSalary
FROM Employee
ORDER BY Salary
OFFSET 1 ROWS FETCH FIRST 1 ROWS ONLY;
-- ORA-00933: SQL command not properly ended
db<>fiddle
Three points. First, in earlier versions of Oracle, you can use window functions:
SELECT Salary as SecondHighestSalary
FROM (SELECT e.*,
ROW_NUMBER() OVER (ORDER BY Salary DESC) as seqnum
FROM Employee e
) e
WHERE seqnum = 2;
Second, this doesn't return the "second highest salary" -- under very reasonable interpretations of the phrase -- because the top salaries can be tied. If you actually want the second highest salary (as opposed to the salary of the person second in the list of ordered salaries), then use RANK() instead of ROW_NUMBER().
Third, you have these insert statements:
insert into Employee (Id, Salary) values ('1', '100');
Both id and Salary are declared as numeric. Don't mix types! The single quotes are not only unnecessary but misleading (although not harmful in this case):
insert into Employee (Id, Salary)
values (1, 100);
Write a query to display department Id, department name, manager id of all departments. If manager id is not available then display 'NA' and give alias name as 'MANAGER_ID'. Sort the result based on department Id. The type of manager_id is number.
select
department_id, department_name, manager_id, NVL(manager_id, 'na') "BONUS_AMT"
from
departments
order by 1;
is my query but the error is ERROR at line 1:
ORA-01722: invalid number
NEED HELP!
You are using an NVL to get a string when a NUMBER is null. If you need a string result, you need to convert your number to string; for example:
SQL> select nvl(x, 'a') from (select 1 x from dual);
select nvl(x, 'a') from (select 1 x from dual)
*
ERROR at line 1:
ORA-01722: invalid
SQL> select nvl(to_char(x, '999'), 'a') from (select 1 x from dual);
NVL(TO_CHAR(X,'999'),'A')
--------------------------------------------------------------------------------
1
select
department_id, department_name, manager_id,
NVL(cast(manager_id as varchar2(10)), 'na') "BONUS_AMT"
from
departments
order by 1;
How to select only one column values without using functions first , last , top , limit in a table ?
Want to use only where command:
ename age
hansen 25
hansen 25
hansen 25
How to select only one values hansen 25 ?
in the above table
Then use DISTINCT:
SELECT DISTINCT ename, age
FROM TableName;
Update: If don't need to use DISTINCT, then you can do the following if you are using sql server:
SELECT ename, age
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY ename DESC) AS row, *
FROM RableName
) sub
WHERE sub.row = 1;
Demo