Update Statement with two tables -Oracle - oracle

I have two tables and I need to Update the second table with a value from first table based on a common column.
I used the below statement
UPDATE emp
2 SET ename = ( SELECT dname
3 FROM dept
4 WHERE emp.deptno = dept.deptno)
5 WHERE EXISTS
6 ( SELECT dname
7 FROM dept
8 WHERE emp.deptno = dept.deptno);
But am getting the error
ORA-01427 - Single row subquery returns more than one row.
Can you plese help me out?

SELECT dname
FROM dept
WHERE emp.deptno = dept.deptno
query must return single record.
check with
SELECT count(*), dname
FROM dept
group by dname
having count(*) > 1
order by 1 desc
or use
SELECT dname
FROM dept
WHERE emp.deptno = dept.deptno
and rownum = 1

You need to check if 1st subquery returns only 1 value bcz if this subquery returns more then 1 row you want to update 1 field ename with 2 values from row and that's why i guess you have this error

Your subquery to dept table is probably not returning one row. Add min or max operation to get one row from dept for each row from emp. Each setting value must be nonambigous.
UPDATE emp
SET ename = ( SELECT min dname
FROM dept
WHERE emp.deptno = dept.deptno)
WHERE EXISTS
( SELECT dname
FROM dept
WHERE emp.deptno = dept.deptno);
Remark1: in default SCOTT schema deptno is primary key, so no error would be encountered.
Remark2: shouldn't your question to be placed in serverfault.com?

Related

How to return 0 incase of empty result in oracle select query?

I have a Query where there is number datatype column. In case of empty resultset O/P is blank. I want 0 in that case.
My query is
select nvl(infodata,0)
from table1
where group_id = 111
and appid in (select max(id)
from table1, table2
where status = 'A');
Now my inner query is returning null in that case. NVL seems to be not working on infodata column. Please help
Outcome of such a query is no rows selected.
For example (based on Scott's EMP and DEPT tables as I don't have yours, and you didn't post test case), this query returns nothing:
SQL> select e.deptno
2 from emp e
3 where e.ename = 'Littlefoot';
no rows selected
If it is used as a subquery, the result is equal to what you currently have:
SQL> select nvl(d.dname, 'x') result
2 from dept d
3 where d.deptno in (select e.deptno
4 from emp e
5 where e.ename = 'Littlefoot'
6 );
no rows selected
But, if you apply aggregation (see line #1), then you'd get what you wanted:
SQL> select nvl(max(d.dname), 'x') result
2 from dept d
3 where d.deptno in (select e.deptno
4 from emp e
5 where e.ename = 'Littlefoot'
6 );
RESULT
--------------
x
As I said: it works on my test case; might, or might not on yours. If you post sample data, we'd have something to work with.

Trying to update table but i always get ora-01427

So i am trying to update my Vorschlagspakete table with some values i got from other tables. Precisely there are 3 values i want to write into the main table. Atm it looks like this:
update vorschlagspakete
set (paketid, verkaufsstelleid) = (
select k.paketid, k.verkaufsstelleid
from Konfiguration k, bewertung b
where k.konfigurationsid = b.konfigurationsid
group by k.paketid, k.verkaufsstelleid
having avg(b.sterne) >= 5);
But every time i tried this it results into ora-01427.
Error you got, ORA-01427, means too many rows (were returned by subquery). For example based on Scott's schema (as I don't have your tables), it looks like this:
SQL> update emp e set
2 (e.ename, e.job) = (select d.dname, d.loc from dept d);
(e.ename, e.job) = (select d.dname, d.loc from dept d)
*
ERROR at line 2:
ORA-01427: single-row subquery returns more than one row
Why wouldn't it work? Because subquery returns more than a single row!
SQL> select d.dname, d.loc from dept d;
DNAME LOC
-------------- -------------
ACCOUNTING NEW YORK
RESEARCH DALLAS
SALES CHICAGO
OPERATIONS BOSTON
SQL>
So, how would you put all those values into a single row of the EMP table? That won't work, obviously, so you have to do something to restrict number of rows. How? Well, it depends.
sometimes DISTINCT helps, e.g.
select distinct d.dname, d.loc from dept d
sometimes additional WHERE condition helps, e.g.
select d.dname, d.loc from dept d
where d.location = 'NEW YORK'
sometimes joining with the table to be updated helps, e.g.
select d.dname, d.loc from dept d where d.deptno = e.deptno
which leads to
SQL> update emp e set
2 (e.ename, e.job) = (select d.dname, d.loc from dept d where d.deptno = e.deptno);
14 rows updated.
What should you do? I don't know, we don't have your data. See whether something written above helps.

not a single-group group function when using max

I am trying to get out the max avrg using query below but I am getting wrror saying
ORA-00937: not a single-group group function
00937. 00000 - "not a single-group group function"
*Cause:
*Action: Error at Line: 1 Column:
SELECT B.STUDENT_ID,
A.FRIST_NAME,
A.FATHER_NAME,
A.LAST_NAME,
SUM (B.GRADE) AS SUM_GRADE,
COUNT(B.COURSE_ID) AS COURSE_COUNT,
max(SUM(B.GRADE) / COUNT(B.COURSE_ID)) AS AVRG
FROM STUDENT A,
STUDENT_COURSE B
WHERE A.STUDENT_ID = B.STUDENT_ID
GROUP BY A.FRIST_NAME, A.FATHER_NAME, A.LAST_NAME, B.STUDENT_ID;
this error gone when I remove the max function any one can help me why ?
I tried to use having maxbut I am getting error that says invalid renational
any way to use having with this query ?
One option is to use your current query (without MAX) as an inline view, and apply the MAX function to "sum/count":
SELECT student_id,
first_name,
father_name,
last_name,
sum_grade,
course_count,
-- this:
MAX(avrg) max_avrt
FROM (-- your current query
SELECT b.student_id,
a.frist_name,
a.father_name,
a.last_name,
SUM(b.grade) AS sum_grade,
COUNT(b.course_id) AS course_count,
SUM(b.grade) / COUNT(b.course_id) AS avrg
FROM student a,
student_course b
WHERE a.student_id = b.student_id
GROUP BY a.frist_name,
a.father_name,
a.last_name,
b.student_id
)
GROUP BY student_id, first_name, father_name, last_name, sum_grade, course_count;
However, you won't achieve anything good, as you'd still get the same record set due to outer GROUP BY clause. Consider using SUM in its analytic form.
Here's a simple example which shows what I mean, based on Scott's schema.
This is what you have now:
SQL> select deptno, sum(sal) / count(*) ssc
2 from emp
3 group by deptno
4 order by deptno;
DEPTNO SSC
---------- ----------
10 2916,66667
20 2258,33333
30 1566,66667
Apparently, you'd like to select the first SSC value (2916). If you apply what I wrote earlier (i.e. use that query as an inline view), you'd get this:
SQL> select deptno, max(ssc) max_ssc
2 from (select deptno, sum(sal) / count(*) ssc
3 from emp
4 group by deptno
5 )
6 group by deptno
7 order by deptno;
DEPTNO MAX_SSC
---------- ----------
10 2916,66667
20 2258,33333
30 1566,66667
SQL>
No improvement, eh? So, analytical function might be what you need:
SQL> select deptno,
2 max(sum(sal) / count(*)) over (order by deptno) max_ssc
3 from emp
4 group by deptno
5 order by deptno;
DEPTNO MAX_SSC
---------- ----------
10 2916,66667
20 2916,66667
30 2916,66667
This does return desired MAX value (if that's what you're looking for. If not, explain what you'd want to get as a result).

Trouble With Basic Query Searching

Not sure if the this is the right place to ask but i have a question with beginner sql.
I have the table dept and emp which include:
SQL> desc dept;
Name Null? Type
----------------------------------------- -------- ----------------------
DEPTNO NUMBER(2)
DNAME VARCHAR2(14)
LOC NOT NULL VARCHAR2(13)
SQL> desc emp;
Name Null? Type
----------------------------------------- -------- ----------------------
EMPNO NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
I need to search for all jobs that are in department 30 and to Include the location of department 30.
What im trying is this:
SQL> select emp.job, dept.deptno, dept.loc
2 from emp, dept
3 where emp.deptno = dept.deptno
4 where deptno = '30';
where deptno = '30'
*
ERROR at line 4:
ORA-00933: SQL command not properly ended
But as you can see its not working and i have tried different variations but still no luck. Am i on the right track? How would I solve this?
It sounds like you want something like this. When you have multiple conditions in the where clause, you only specify where once and combine them with and or or conditions.
select emp.job, dept.deptno, dept.loc
from emp, dept
where emp.deptno = dept.deptno
and dept.deptno = 30;
Unless there is some reason that you really need to use the old join syntax, you probably ought to start with the SQL 99 syntax. It makes it much easier to move between databases, it makes your queries easier to read by separating join and filter conditions, and it makes life much easier when you start working on outer joins.
select emp.job, dept.deptno, dept.loc
from emp
join dept
on( emp.deptno = dept.deptno )
where dept.deptno = 30;

How can i select just one row in Oracle by row id?

I have used mysql database in my application, but I want to migrate to Oracle.
The problem is in that query:
select * from users limit ?,1;"
That query returns every row one by one depending on ?.
How can i do that in oracle?
On Oracle 12c, you could use the row limiting feature using FETCH FIRST clause.
SQL> SELECT empno, sal, deptno FROM emp ORDER BY empno DESC
2 FETCH FIRST 1 ROWS ONLY;
EMPNO SAL DEPTNO
---------- ---------- ----------
7934 1300 10
SQL>
Prior 12c solution is ROWNUM, however, if you want the row to be first sorted, then you need to do it in a sub-query -
SQL> SELECT empno, sal, deptno FROM
2 ( SELECT * FROM emp ORDER BY empno DESC
3 ) WHERE ROWNUM = 1;
EMPNO SAL DEPTNO
---------- ---------- ----------
7934 1300 10
SQL>
If the order doesn't matter to you, if you just want any random row, simply use ROWNUM.
Depending on your requirement, you could also use ANALYTIC functions such as ROW_NUMBER, RANK, DENSE_RANK.
select * from (select rownum r, u.* from users u ) where r=1;
or if you want it sorted (replace x by columnnumber or columnname):
select * from (select rownum r, u.* from users u order by x) where r=1;

Resources