Swap these two columns without using update in Oracle sql? - oracle

Ename sex
ABC male
Def female
Swap between male & female.
Output should be
Male ABC
Female DEF
Thanks in advance!
Preparing for Interview.

I'm going to assume you have a table defined like:
CREATE TABLE EMP
(ENAME VARCHAR2(20),
SEX VARCHAR2(6));
and that you have the following rows in it:
ENAME SEX
ABC male
Def female
I'll further assume that the output in your question was the result of executing
SELECT * FROM EMP
Now, to answer your question - to get SEX first, then ENAME, try the following:
SELECT SEX, ENAME FROM EMP
If you're trying to concatenate the values of SEX and ENAME so you get back a single column try
SELECT SEX || ' ' || ENAME AS SEX_AND_NAME FROM EMP
Share and enjoy.

The answer is as below: Assuming table name is EMP
UPDATE TABLE EMP
SET ENAME = SEX,
SEX = ENAME;
This will swap the values of the columns ename and sex not the column position.

Related

How can I display column names in the result of queries?

I'm trying to display the name of columns on the top of my file instead of getting only the data I wanna also get the name of the columns
I'm using ORACLE 12C
What you described sounds as if you turned headings off in SQL*Plus. Something like this: by default, headings are visible:
SQL> select * from dept where deptno = 10;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
If you turn them off:
SQL> set heading off
SQL>
SQL> select * from dept where deptno = 10;
10 ACCOUNTING NEW YORK
While display logic should usually be handled in the application, there are workarounds to accomplish something similar with SQL. The below statement uses a few tricks to create an initial row of column names:
select name, age, nationality, city
from
(
select 1 header_1_data_2, 'Name' name, 'Age' age, 'Nationality' nationality, 'City' city
from dual
union all
select 2 header_1_data_2, name, to_char(age), nationality, city
from student
)
order by header_1_data_2;

How to use a rowcount in select statement to modify the query to fetch data for 10 days , if rowcount is 0 for 5 days?

I need to modify my script using rowcount to check if the data in table or not?. Here, i write the query to select a data for last 5 days from current system date. But sometimes there is no data in table for 5 days. So i need to fetch for 10 day or more.
Query:
Select ep.ENTERPRISE_NAME||'|'||s.id||'|'||s.SUBMISSION_DATE||'|'||E.VALUE
from JOB_SUMMARY_EXT e, ob_summary s, enterprise ep
where e.id = s.id and e.name_res_key = 'Model'
and s.job_id in (select id from job_summary where
trunc(start_date) > trunc(sysdate) -10 and service_name ='Model2' )
I don't know how to modify my Query using rowcount. If rowcount is 0 then i want select data for 10 days.Otherwise it should to fetch for 5 days automatically. I want this to be done as single query.
It looks that you want to select the last 5 "days" from that table. So, why would you anchor to SYSDATE if there aren't rows for each of those days? I'd suggest another approach: literally, select last 5 days. Here's how.
As I don't have your tables, I'm using Scott's EMP table which contains information about employees. It is an ancient one so HIREDATE column is set to 1980s, but never mind that. Sorting employees by HIREDATE in descending order shows:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> select ename, hiredate from emp order by hiredate desc;
ENAME HIREDATE
---------- ----------
ADAMS 12.01.1983 1.
SCOTT 09.12.1982 2.
MILLER 23.01.1982 3.
FORD 03.12.1981 4.
JAMES 03.12.1981 4.
KING 17.11.1981 5. --> I want to fetch rows up to KING
MARTIN 28.09.1981
TURNER 08.09.1981
CLARK 09.06.1981
BLAKE 01.05.1981
JONES 02.04.1981
WARD 22.02.1981
ALLEN 20.02.1981
SMITH 17.12.1980
14 rows selected.
SQL>
As you can see, the 4th date is shared by two employees so I want to include them both. DENSE_RANK analytic function helps:
SQL> with last5 as
2 (select ename,
3 job,
4 sal,
5 hiredate,
6 dense_rank() over (order by hiredate desc) rnk
7 from emp
8 )
9 select ename, job, sal, hiredate
10 from last5
11 where rnk <= 5;
ENAME JOB SAL HIREDATE
---------- --------- ---------- ----------
ADAMS CLERK 1100 12.01.1983
SCOTT ANALYST 3000 09.12.1982
MILLER CLERK 1300 23.01.1982
JAMES CLERK 950 03.12.1981
FORD ANALYST 3000 03.12.1981
KING PRESIDENT 5000 17.11.1981
6 rows selected.
SQL>
What does it do? The LAST5 CTE sorts employees (as above), DENSE_RANK ranks them; finally, the last SELECT (which begins at line #9) fetches desired rows.
In your case, that might look like this:
with last5 as
(select id,
dense_rank() over (order by start_date desc) rnk
from job_summary
where service_name = 'Model2'
)
select ep.enterprise_name,
s.id,
s.submission_date,
e.value
from job_summary_ext e
join ob_summary s on e.id = s.id
join last5 t on t.id = s.id
join enterprise ep on <you're missing join condition for this table>
where e.name_res_key = 'Model';
Note that you're missing join condition for the ENTERPRISE table; if that's really so, no problem - you'd use cross join for that table, but I somehow doubt that you want that.
Finally, as you use SQL*Plus, perhaps you don't need to concatenate all columns and separate them by the pipe | sign - set it as a column separator, e.g.
SQL> set colsep '|'
SQL>
SQL> select deptno, dname, loc from dept;
DEPTNO|DNAME |LOC
----------|--------------|-------------
10|ACCOUNTING |NEW YORK
20|RESEARCH |DALLAS
30|SALES |CHICAGO
40|OPERATIONS |BOSTON
SQL>
If you want to
return 10 last days if select count(*) returns 0, or
return 5 last days if select count(*) returns a positive number
then something like this might help (again based on Scott's EMP table):
with
tcnt as
-- count number of rows; use your own requirement, I'm checking
-- whether someone got hired today. In Scott's EMP table, nobody was
-- so CNT = 0
(select count(*) cnt
from emp
where hiredate >= trunc(sysdate)
)
select e.ename, e.job, e.sal, e.hiredate
from emp e cross join tcnt c
where e.hiredate >= case when c.cnt = 0 then trunc(sysdate) - 10
else trunc(sysdate) - 5
end;
Apply it to your tables; I don't know which of those 3 tables' count you want to check.
Tried to add in comments but it was too long for comments and Not clear on count based on but here is case in where clause substitute your count statement with nvl function
SELECT ep.ENTERPRISE_NAME||'|'||s.id||'|'||s.SUBMISSION_DATE||'|'||E.VALUE
FROM JOB_SUMMARY_EXT e,
ob_summary s,
enterprise ep
WHERE e.id = s.id
AND e.name_res_key = 'Model'
AND s.job_id IN
(SELECT id
FROM job_summary
WHERE service='Model'
AND trunc(start_date) >
CASE WHEN
(WRITE your SELECT COUNT criteria WITH NVL FUNCTION)<=0 THEN
trunc(sysdate) -10
ELSE trunc(sysdate)-5
END )

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;

the number of same record until this row

Is it possible to retrieve current number of same record for each row by using oracle pl/sql?
For example,
I have class table which consists of id, name, age columns
I want to have the sequence of student with the same name and age entering the class, assuming that id is countering up without altering data structure.
Thanks.
Regards,
Jim
Not sure I entirely get what you're asking for; you have an odd turn of phrase. An example of input data and expected result is always useful.
Perhaps something like this:
select id, name, age
from your_table
where (name, age) in
( select name. age
from your_table
group by name, age
having count(id) > 1 )
order by name, age, id
/
You could solve this with analytics. However, you still need an outer query to filter out the records which aren't duplicated, so I'm not sure what you'd gain:
select * from (
select id, name, age
, count(id) over (partition by name, age) as dup_count
from your_table )
where dup_count > 1
order by name, age, id
/
I'm not sure either, but it sounds to me something related to analytic functions. Take this as an example, look at srlno column, calculated using analytic functions:
SELECT empno, deptno, hiredate,
ROW_NUMBER( ) OVER (PARTITION BY
deptno ORDER BY hiredate
NULLS LAST) SRLNO
FROM emp
WHERE deptno IN (10, 20)
ORDER BY deptno, SRLNO;
EMPNO DEPTNO HIREDATE SRLNO
------ ------- --------- ----------
7782 10 09-JUN-81 1
7839 10 17-NOV-81 2
7934 10 23-JAN-82 3
7369 20 17-DEC-80 1
7566 20 02-APR-81 2
7902 20 03-DEC-81 3
7788 20 09-DEC-82 4
7876 20 12-JAN-83 5
More on analyltic functions:
http://www.orafaq.com/node/55
Remember, is a better approach if you can achieve your goal with a SQL instead of PL/SQL.

How to update One table column values with another table's column values? [duplicate]

This question already has answers here:
Update rows in one table with data from another table based on one column in each being equal
(5 answers)
Closed 9 years ago.
i have table called Student with columns uniquename, age,department,city,Homecountry and another table called Employee with columns uniquename, exp,qualification, Homecountry.
now i want to update Student table's department column with Employee table's qualification column values under the where condition Student.uniquename = Employee.uniquename and Student.Homecountry = Employee.Homecountry.
please help me to write the update statement.
This kind of query is called a correlated sub query. For your requirement, the query would be as below....
update students s
set s.department = (
select e.qualification
from employee e
where s.uniquename = e.uniquename
and s.Homecountry = e.Homecountry
);
updating this post based on your replies below.
Again, going forward, always post the create table and insert statements (and the expected results) to reproduce your case. If you don't see the expected results or if you see an erro when you execute the query, post the exact message instead of just saying "not working". Here is the results of my sqlplus session.
---create table and insert statements
create table student(
name varchar2(20),
age number,
department varchar2(3),
HomeCountry varchar2(10)
);
Table created.
create table employee5(
name varchar2(20),
exp number,
qualification varchar2(3),
homecountry varchar2(10)
);
Table created.
insert into student values ('Mohan',25,'EEE','India');
insert into student values ('Raja',27,'EEE','India');
insert into student values ('Ahamed',26,'ECE','UK');
insert into student values ('Gokul',25,'IT','USA');
commit;
insert into employee5 values ('Mohan',25,'ECE','India');
insert into employee5 values ('Raja',24,'IT','India');
insert into employee5 values ('Palani',26,'ECE','USA');
insert into employee5 values ('Sathesh',29,'CSE','CANADA');
insert into employee5 values ('Ahamed',28,'ECE','UK');
insert into employee5 values ('Gokul',29,'EEE','USA');
commit;
Before updating the data...
SQL> select * from student;
NAME AGE DEP HOMECOUNTR
-------------------- ---------- --- ----------
Mohan 25 EEE India
Raja 27 EEE India
Ahamed 26 ECE UK
Gokul 25 IT USA
SQL> select * from employee5;
NAME EXP QUA HOMECOUNTR
-------------------- ---------- --- ----------
Mohan 25 ECE India
Raja 24 IT India
Palani 26 ECE USA
Sathesh 29 CSE CANADA
Ahamed 28 ECE UK
Gokul 29 EEE USA
Update statement and results
1 update student s set s.age =
2 ( select e.exp
3 from employee5 e
4 where e.name = s.name
5 and e.homecountry = s.homecountry
6* )
SQL> /
4 rows updated.
SQL> select * from student;
NAME AGE DEP HOMECOUNTR
-------------------- ---------- --- ----------
Mohan 25 EEE India
Raja 24 EEE India
Ahamed 28 ECE UK
Gokul 29 IT USA
SQL> commit;
Commit complete.
update student s
set s.age = (select e.exp
from employee5 e
where e.name = s.name
and e.homecountry = s.homecountry
and rownum < 2
)
where s.age in (select age from employee5)
It wont show the message subquery returns more than one record

Resources