Oracle sql query returning all of the values instead limiting the values - oracle

full disclosure this is part of a homework question but I have tried 6 different versions and I am stuck.
I am trying for find 1 manager every time the query runs. I.e I put the department id in and 1 name pops out. currently, I get all the names, multiple times. I have tried a nesting with an '=' not nesting, union, intersection, etc. I can get the manager id with a basic query, I just can't get the name. the current version looks like this:
select e.ename
from .emp e
where d.managerid in (select unique d.managerid
from works w, .dept d, emp e1
where d.did=1 and e1.eid=w.eid and d.did=w.did );
I realize its probably a really basic mistake that I am not seeing - any ideas?

Its not clear what do you mean get 1 menager any time. are it should be different menagers any time or the same?
Lest go throw your query:
you select all empolyes from table emp where manager_id in next query dataset
You get all managers for dep=1. The rest of tables and conditions are not influent on result dataset.
I theing did is primary key for table dept, If so your query may be rewritten to
select e.ename
from emp e
where d.managerid in (select unique d.managerid
from dept d
where d.did=1);
but this query return to you all emploees and not manager from dept=1
and if you need a manager. you should get emploee who is a manager. If eid is primary key of employee, and managerid is id from employee table you need something like:
select e.ename
from emp e
where e1.eid in (select unique d.managerid
from dept d
where d.did=1);

Related

Update Oracle table by amount of rows

If I run the below query I m going to update an Oracle table by 7K rows. I want to do that by 300 of records per time.
INSERT INTO REQUEST
SELECT REQUEST_SEQ.NEXTVAL, REQUEST_ID, 'TEST', REF_ASK_ID, SYSDATE
FROM CITIES
INNER JOIN REFERENCE ON CITY_ID = REF_ID
WHERE REF_ASK_NM= 'DOWN'
AND CITY_WAY IN ('1', '33')
300 rows at a time? Why? To make it slower?
Anyway:
rownum will make sure to take 300 rows
not exists will make sure not to copy what you already have copied (if where condition catches them all).
I don't know which columns belong to which tables as you didn't use table aliases (and yes, you should have)
if there are duplicates for columns being used in where, you might still get duplicates as there's no guarantee that that "set" of rows will be inserted as a whole
In other words: do it all at once.
INSERT INTO offices
SELECT office_seq.NEXTVAL, office_id, office_ref
FROM city INNER JOIN reference ON office_id = ref_id
WHERE ROWNUM <= 300
AND NOT EXISTS
(SELECT NULL
FROM offices b
WHERE b.office_id = city.office_id -- or maybe reference.office_id
AND b.office_ref = city.office_ref); -- or maybe reference.office_ref

Removing duplicate columns in one row while merging corresponding column values

Apologies if this seems simple to some, I am still in the (very) early stages of learning!
Basically I've got a table database that has multiple users (Users_ID), each with a corresponding access name(NAME). The problem is, some Users have multiple access names, meaning when the data is pulled, there is duplicates in the User_ID column.
I need to remove the duplicates in the User column and join their corresponding access names in the NAME column, so it only takes up 1 row and no data is lost.
The current SQL query I'm using is :
select Table1_user_id, Table2.name,
from Table1
inner join Table2
on Table1.role_id = Table2.role_id
An example of what this would return:
USER_ID | NAME
------- --------------
Tim Level_1 Access
John Level 2 Access
Tim Level 2 Access
Mark Level 3 Access
Tim Level 3 Access
Ideally, I would remove the duplicates for Tim and display as following:
USER_ID | NAME
------- ----------------------------------------------
Tim Level_1 Access, Level 2 Access, Level 3 Access
John Level 2 Access
Mark Level 3 Access
Thanks in advance for any help regarding this and sorry if something similar has been asked before!
Use GROUP_CONCAT with SEPARATOR :
SELECT Table1.user_id, GROUP_CONCAT(Table2.name SEPARATOR ',') AS Ename
FROM Table1
INNER JOIN Table2 ON Table1.role_id = Table2.role_id
GROUP BY Table1.user_id
select Table1_user_id, LISTAGG(Table2.name,', ') WITHIN GROUP (ORDER BY Table2.name) as Name
from Table1
inner join Table2
on Table1.role_id = Table2.role_id

Oracle view to return single column from multiple select columns

query 1: I need to get the dept code from one table.
query 2: use that dept code to query another table which also has got another set of dept code. kind of one is to many, one dept referring to many depts.
NOTE: they don't have the same column name in two tables.
and the final result should be union of 1st query and 2nd query.
for eg: query 1 result : ECE
query 2 result : EEE, Mech, Comp. Sc.
I need the result to be ECE, EEE, Mech, Comp. Sc.
declare default_dept_Code varchar2(10);
begin
select dept_code into default_dept_Code from (select dept_code from
course_per WHERE student_no ='526765771');
dbms_output.put_line(default_dept_Code);
SELECT dept_code FROM course_per WHERE student_no ='526765771'
union all
select add_dept_code from addition_dept where dept_Code = default_dept_Code;
I'm unable to execute this query, it has got error. What are the other best ways I can handle it, I need to put this in a VIEW. I tried to create temp table and insert the select result into it, did not work. I'm a new bee to Oracle. I don't want to use cursor, if that is the only option I can go for it.
From what I understand you can write your query like this:
SELECT dept_code as code
FROM course_per
WHERE student_no ='526765771'
UNION ALL
SELECT add_dept_code as code
FROM addition_dept
WHERE dept_Code = (
SELECT dept_code
FROM course_per
WHERE student_no ='526765771');

pl-sql include column names in query

A weird request maybe but. My boss wants me to create an admin version of a page we have that displays data from an oracle query in a table.
The admin page, instead of displaying the data (query returns 1 row), needs to return the table name and column name
Ex: Instead of:
Name Initial
==================
Bob A
I want:
Name Initial
============================
Users.FirstName Users.MiddleInitial
I realize I can do this in code but would rather just modify the query to return the data I want so I can leave the report generation code mostly alone.
I don't want to do it in a stored procedure.
So when I spit out the data in the report using something like:
blah blah = MyDataRow("FirstName")
I can leave that as is but instead of it displaying "BOB" it would display "Users.FirstName"
And I want to do the query using select * if possible instead of listing all the columns
So for each of the columns I am querying in the * , I want to get (instead of the column value) the tablename.ColumnName or tablename|columnName
hope you are following- I am confusing myself...
pseudo:
select tablename + '.' + Columnname as WhateverTheColumnNameIs
from Table1
left join Table2 on whatever...
Join Table_Names on blah blah
Whew- after writing all this I think I will just do it on the code side.
But if you are up for it maybe a fun challenge
Oracle does not provide an authentic way(there is no pseudocolumn) to get the column name of a table as a result of a query against that table. But you might consider these two approaches:
Extract column name from an xmltype, formed by passing cursor expression(your query) in the xmltable() function:
-- your table
with t1(first_name, middle_name) as(
select 1,2 from dual
), -- your query
t2 as(
select * -- col1 as "t1.col1"
--, col2 as "t1.col2"
--, col3 as "t1.col3"
from hr.t1
)
select *
from ( select q.object_value.getrootelement() as col_name
, rownum as rn
from xmltable('//*'
passing xmltype(cursor(select * from t2 where rownum = 1))
) q
where q.object_value.getrootelement() not in ('ROWSET', 'ROW')
)
pivot(
max(col_name) for rn in (1 as "name", 2 as "initial")
)
Result:
name initial
--------------- ---------------
FIRST_NAME MIDDLE_NAME
Note: In order for column names to be prefixed with table name, you need to list them
explicitly in the select list of a query and supply an alias, manually.
PL/SQL approach. Starting from Oracle 11g you could use dbms_sql() package and describe_columns() procedure specifically to get the name of columns in the cursor(your select).
This might be what you are looking for, try selecting from system views USER_TAB_COLS or ALL_TAB_COLS.

How to work around ORA-02014: cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc

I want to lock one record in a table.
The record is specified as "the next that has ID greater than..."
CREATE TABLE test (id number);
SELECT id
FROM (SELECT id
FROM test
WHERE id > 10
ORDER BY id)
WHERE ROWNUM = 1
FOR UPDATE;
This seems intuitive and easy. But it is not. Any ideas?
P.S.
I do need the existing query to remain the same because it is a cursor and there are several places that use this cursor's %rowtype.
I think you're going to need something like:
SELECT id
FROM test
WHERE id =
(SELECT MIN(id)
FROM test
WHERE id > 10)
FOR UPDATE;

Resources