Help with a tricky sql
** Consider the following table; we'll name this 'entities' for
the following discussion.
ENTITY FORM DEPTH EQUIV SOURCE
100012802307W502 DVNU 1458 14399 GOVT
100012802307W502 DVNU 1458 14399 IPL
100012802307W502 PLSR 1455 14399 GOVT
100012802307W502 PLSR 4238 14399 wayrig
100012802307W502 PLSR 4450.4 14399 GOVT
100012802307W502 PLSR 4788.3 14399 GOVT
101070403227W300 BGVL 800 14399 GOVT
101070403227W300 DVNU 855.3 14390 IPL
101070403227W300 DVNU 855.6 14399 GOVT
** The goal
For each unique ID (only 2 in the above example table: 100012802307W502
and 101070403227W300)
We need to get a single 'formation pick'.
Without going into details, 'formation pick' is an industry term and
in our example, a formation pick is identified by the FORM attribute.
** The Problem
Given the above, the question which I need to answer is
for each unique ENTITY, I want to get the PLSR formation pick.
If for any ENTITY, there is not a PLSR pick, but there is
an EQUIVALENT pick then for that ENTITY, we want that equivalent pick
(in our example above, all FORM which have the same EQUIV value are
considered equivalent; thus for 100012802307W502, there are PLSR picks
while for 101070403227W300, there are not but there are equivalent
picks (DVNU and BGVL)
The picks are to be selected based on a priority
top priority is given to SOURCE wayrig
If a given pick does not have a wayrig, SOURCE, then accept IPL
Finally, if neither the wayrig, or IPL SOURCE are available,
accept the GOVT pick
Thus, for 100012802307W502, where there are multiple PLSR picks, we
want the one with the highest available priority
(the 100012802307W502 PLSR 4238 14399 wayrig)
row
For 101070403227W300, which does not have a PLSR pick, we need to consider
the qualifying equivalent picks and the highest applicable priority for
these picks is where SOURCE = GOVT -> rows
101070403227W300 BGVL 800 14399 GOVT
101070403227W300 DVNU 855.6 14399 GOVT
Thus, the final condition that
should there be 2 or more picks whose priority is the same, then we
want the one with the shallowest DEPTH
row
101070403227W300 BGVL 800 14399 GOVT
Thus the desired final results
ENTITY FORM DEPTH EQUIV SOURCE
100012802307W502 PLSR 4238 14399 wayrig
101070403227W300 BGVL 800 14399 GOVT
** Constraints
It is most desireable to achieve this without having to create
physical tables and/or views as the query(ies) must run against
a public database where users do not have create table privileges.
If anyone has solutions that include physical tables, please submit
these anyways as they may help us devise the ultimate approach that
we are seeking.
More info (in case this is helpful)
I have been working on this and variations of this problem for
a little while.
Here is a query that was submitted to me via this discussion group
sometime ago on a similar problem
select ENTITY, FORM, MIN(DECODE ( SOURCE,'wayrig',1,'IPL',2, 3)) PICK_PRIORITY
from entities
where EQUIV = '14399'
GROUP BY ENTITY, FORM
ENTITY FORM PICK_PRIORITY
100012802307W502 DVNU 2
100012802307W502 PLSR 1
101070403227W300 BGVL 3
101070403227W300 DVNU 3
as you can see, the above query gets me partially where I need to go.
Unfortunately, I have not been able to adapt the above query in such a
way as to get the rest of the information related to the selected ENTITY;
that is, the DEPTH, EQUIV, and SOURCE values are not present in the
selected data.
And of course, the above is only a piece of the puzzle as it does not
get me a single row per selected ENTITY.
Thanks for your consideration
null
"bounoe",
I am a little bit confused, because what you are asking for and the sample result seem to be in slight conflict. What you ask for does not require that equiv = '14399', but your results seem to.
So, if equiv must equal '14399', then
SELECT DISTINCT entity, form, depth, equiv, source
FROM entities
WHERE equiv = '14399'
AND (entity,
DECODE(form,'PLSR',1,2),
depth,
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)) IN
(SELECT entity,
DECODE(form,'PLSR',1,2),
MIN(depth),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)
FROM entities
WHERE equiv = '14399'
AND (entity,
DECODE(form,'PLSR',1,2),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)) IN
(SELECT entity,
DECODE(form,'PLSR',1,2),
MIN(DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4))
FROM entities
WHERE equiv = '14399'
AND (entity,DECODE(form,'PLSR',1,2)) IN
(SELECT entity,
MIN(DECODE(form,'PLSR',1,2))
FROM entities
WHERE equiv = '14399'
GROUP BY entity)
GROUP BY entity,DECODE(form,'PLSR',1,2))
GROUP BY entity,
DECODE(form,'PLSR',1,2),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4));
ENTITY FORM DEPTH EQUIV SOURCE
100012802307W502 PLSR 4238 14399 wayrig
101070403227W300 BGVL 800 14399 GOVT
If equiv need not equal '14399':
SELECT DISTINCT entity, form, depth, equiv, source
FROM entities
WHERE (entity,
DECODE(form,'PLSR',1,2),
depth,
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)) IN
(SELECT entity,
DECODE(form,'PLSR',1,2),
MIN(depth),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)
FROM entities
WHERE (entity,
DECODE(form,'PLSR',1,2),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4)) IN
(SELECT entity,
DECODE(form,'PLSR',1,2),
MIN(DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4))
FROM entities
WHERE (entity,DECODE(form,'PLSR',1,2)) IN
(SELECT entity,
MIN(DECODE(form,'PLSR',1,2))
FROM entities
GROUP BY entity)
GROUP BY entity,DECODE(form,'PLSR',1,2))
GROUP BY entity,
DECODE(form,'PLSR',1,2),
DECODE(source,'wayrig',1,'IPL',2,'GOVT',3,4));
ENTITY FORM DEPTH EQUIV SOURCE
100012802307W502 PLSR 4238 14399 wayrig
101070403227W300 DVNU 855 14390 IPL
If neither of these is exactly what you need, please let me know.
Barbara
null
Similar Messages
-
Help with anonymus pl/sql layout using javascript
Hi people.
i want to display some records on a region (using apex 4.2) , this anonymous pl/sql script below shows 3 records from database, but the layout only shows me the first record with it's data, the others 2 records, only show me labels.
i have verified this same query creating a report and it shows the 3 records correctly.
i guess i am doing something wrong with this javascript routine or i am surely missing something,
in this link you can see the layout i am getting. (http://sdrv.ms/Xrv0J8).
the other little help i need is to display in one row for each record. actually i am getting one row for each label and one row for each data record. i have read and found is something about /div, but i don't no how to change it to get desired results, any suggestion is welcome.
thanks in advance for any help.
i am completely new in apex and java script, but i have several years experience in pl/sql.
The Script :
Begin
Declare
Cursor Deliv Is
Select item,
To_char (Delivery, 'month dd, yyyy hh24:mi:ss') Delivery,
Current_date
From pending_items;
Begin
For A In Deliv Loop
Begin
Sys.Htp.P ('<script type="text/javascript">');
Sys.Htp.P ('function cdtd() {');
Sys.Htp.P (' var xmas = new Date("' || a.delivery || '")');
Sys.Htp.P (' var now = new Date();');
Sys.Htp.P (' var timeDiff = xmas.getTime() - now.getTime();');
Sys.Htp.P (' if (timeDiff <= 0) {');
Sys.Htp.P (' clearTimeout(timer);');
-- Sys.Htp.P (' document.write("Some Text Here!");');
Sys.Htp.P (' // Run any code needed for countdown completion here');
Sys.Htp.P (' }');
Sys.Htp.P (' var seconds = Math.floor(timeDiff / 1000);');
Sys.Htp.P (' var minutes = Math.floor(seconds / 60);');
Sys.Htp.P (' var hours = Math.floor(minutes / 60);');
Sys.Htp.P (' var days = Math.floor(hours / 24);');
Sys.Htp.P (' hours %= 24;');
Sys.Htp.P (' minutes %= 60;');
Sys.Htp.P (' seconds %= 60;');
Sys.Htp.P (' document.getElementById("daysBox").innerHTML = days;');
Sys.Htp.P (' document.getElementById("hoursBox").innerHTML = hours;');
Sys.Htp.P (' document.getElementById("minsBox").innerHTML = minutes;');
Sys.Htp.P (' document.getElementById("secsBox").innerHTML = seconds;');
Sys.Htp.P (' var timer = setTimeout("cdtd()",1000);');
Sys.Htp.P ('}');
Sys.Htp.P ('</script>');
Sys.Htp.P ('Days ');
Sys.Htp.P ('<div id="daysBox"></div>');
Sys.Htp.P ('Hours');
Sys.Htp.P ('<div id="hoursBox"></div>');
Sys.Htp.P ('Minutes');
Sys.Htp.P ('<div id="minsBox"></div>');
Sys.Htp.P ('Seconds');
Sys.Htp.P ('<div id="secsBox"></div>');
Sys.Htp.P ('<script type="text/javascript">');
Sys.Htp.P ('cdtd();</script>');
End;
End Loop;
End;
End;Let's focus on your delivery dates and javascript for now.
Why you would put your javascript in htp.p calls in a plsql region is quite beyond me. When you edit the page there is a javascript region where you can put global variables and functions, an excellent spot for this then, and a lot more maintainable than this.
Now it's also obvious that your query on pending items will return more than one record. So, using a report would serve you well in this case. However, using code like this:
document.getElementById("daysBox").innerHTML = days;
document.getElementById("hoursBox").innerHTML = hours;
document.getElementById("minsBox").innerHTML = minutes;
document.getElementById("secsBox").innerHTML = seconds;will not serve you. getElementById is meant to return one element uniquely identified by an ID. If you have a report with multiple rows, and elements on each row with the same ID, you are doing something wrong. You would need the delivery date per row, and I guess that you put out your code with htp.p because you do not know how to deal with that and passing it in to the javascript procedure.
But wouldn't it be more oppurtune for you to simply create a report with a source sql where you calculate each part of the date, and then refresh this region with a certain interval. If you'd refresh every 5 minutes, wouldn't that be more than fast enough to keep track of things? Don't forget, refreshing a region will execute the sql again.
It's not that you can't accomplish a multirecord report with a countdown per row, but are you comfortable enough with javascript and jquery to code and maintain that versus leveraging plsql and dynamic actions (there is even a dynamic action timer plugin provided by oracle)? -
Help with some PL/SQL Triggers
hello there, I'm totally new using PL/SQL so I need your help with two triggers.
For instance
1. Compare two dates, and verify that there are different, you must send a message Error
2. When I insert a new record, a trigger must obtain data from other tables and add it (on a new record)
Maybe not the answers, maybe the way to go!
Thks!Hi,
Welcome to the forum
1. Compare two dates, and verify that there are different, you must send a message Errorwhy trigger ?
Trigger is Only for when DML Performed :)
try 1st one in procedure..
create or replace procedure testing(p_date in date)
is
v_date date;
begin
select to_date(hiredate,'mm-dd-rr') into v_date
from emp
where to_date(hiredate,'mm-dd-rr')=to_date(p_date,'mm-dd-rr');
dbms_output.put_line(v_date);
exception
when others then
dbms_output.put_line('No Data Found');
end;
2. When I insert a new record, a trigger must obtain data from other tables and add it (on a new record)i didn't understand can you please explain me in detail ?
Thanks
Venkadesh -
Please help with workflow inspired SQL
Hi everyone, I need some help with a piece of sql I need to create. It will be used in a workflow scenario and is therefore a bit hairy and has some limitations. So here goes..
I have 2 current tables that will be used in this query. The first is a table used as a supervisor cross reference, and the second will be used for signing authority, or approval authorization. In short...the first table will give you the supervisor for the particular employee or employee in the where clause. This tells us who to route to. The second table has the operators authority level. As an example.... 1, 2, 3, or 4. A 1 could signify that this supervisor can approve for up to $5,000, and a 4 could signify that this person can approve up to $250,000. thats the basic idea.
So what I need to do in ONE statement is get the requestor's supervisor, and then check his/hers authority level for level 1, 2, 3 or 4. The authority level needed will be passed into the query, so I will have that as well as the requestor. And here is the hard part...... If no rows are returned (the supervisor does not have authority to approve) I need the query to apply the same logic to the next supervisor. In other words, the supervisor's supervisor. Every requestor will have a supervisor. Every supervisor will also have a supervisor....so it goes until we get to the CEO. So the query needs to keep going until it finds a row matching the signing authority.
So the limitations are......this needs to happen in one SQL query, and this query can only return ONE field!
Here are some creates and inserts to give you something to work with. Been suffering with this one for a few days so your help is GREATLY appreciated.
Supervisor cross reference table
CREATE TABLE PS_ROLEXLATOPR (ROLEUSER VARCHAR2(30) DEFAULT ' ' NOT
NULL,
DESCR VARCHAR2(30) DEFAULT ' ' NOT NULL,
OPRID VARCHAR2(30) DEFAULT ' ' NOT NULL,
EMAILID VARCHAR2(70) DEFAULT ' ' NOT NULL,
FORMID VARCHAR2(70) DEFAULT ' ' NOT NULL,
WORKLIST_USER_SW VARCHAR2(1) DEFAULT 'Y' NOT NULL,
EMAIL_USER_SW VARCHAR2(1) DEFAULT 'Y' NOT NULL,
FORMS_USER_SW VARCHAR2(1) DEFAULT 'Y' NOT NULL,
EMPLID VARCHAR2(11) DEFAULT ' ' NOT NULL,
ROLEUSER_ALT VARCHAR2(30) DEFAULT ' ' NOT NULL,
ROLEUSER_SUPR VARCHAR2(30) DEFAULT ' ' NOT NULL,
EFFDT_FROM DATE,
EFFDT_TO DATE) TABLESPACE PTTBL STORAGE (INITIAL 40000 NEXT 100000
MAXEXTENTS UNLIMITED PCTINCREASE 0) PCTFREE 10 PCTUSED 80
INSERT INTO PS_ROLEXLATOPR
DESCR,
OPRID ,
EMAILID ,
FORMID ,
WORKLIST_USER_SW ,
EMAIL_USER_SW ,
FORMS_USER_SW ,
EMPLID ,
ROLEUSER_ALT ,
ROLEUSER_SUPR ,
EFFDT_FROM
VALUES
DESCR,
'ABC123',
'XYZ123',
Signing Authority table..
CREATE TABLE PS_ZZ_WF_AUTHORITY (OPRID VARCHAR2(30) NOT NULL,
EMPLID VARCHAR2(11) NOT NULL,
EMAILID VARCHAR2(70) NOT NULL,
ZZ_SIGN_AUTHORITY VARCHAR2(1) NOT NULL) TABLESPACE APLARGE STORAGE
(INITIAL 40000 NEXT 100000 MAXEXTENTS UNLIMITED PCTINCREASE 0)
PCTFREE 10 PCTUSED 80
insert into PS_ZZ_WF_AUTHORITY
OPRID,
EMPLID,
EMAILID,
ZZ_SIGN_AUTHORITY
Values
'XYZ123',
'Any_Email',
'1'
)Hi,
Welcome to the forum!
Thanks for posting the CREATE TABLE and INSERT statements; that's very helpful!
Whenever you have a question, also post the results you want to get from the sample data your posted.
Always say what version of Oracle you're suing.
In the sample data you posted, I only see one row in each table. Does that really give a good picture of the problem? If the problem involves going up the chain of command 1, 2, 3 or more levels, then shouldn't you have a chain of at least 3 people to show the problem and test the results?
I think what you need is CONNECT BY Query , which works on a table with a parent-child relationship. Given a parent, you can find that ow's children, the children's children, their children, and so on, however many generations there are.
I don't think I can demonstrate this with your sample data, so I'll use the scott.emp table, whcih you should be able to query.
The emp table contains a hierarcy of employees, including this data:
NAME EMPNO MGR SAL JOB
KING 7839 5000 PRESIDENT
JONES 7566 7839 2975 MANAGER
SCOTT 7788 7566 3000 ANALYST
ADAMS 7876 7788 1100 CLERK
FORD 7902 7566 3000 ANALYST
SMITH 7369 7902 800 CLERK
BLAKE 7698 7839 2850 MANAGER
ALLEN 7499 7698 1600 SALESMAN
WARD 7521 7698 1250 SALESMAN
MARTIN 7654 7698 1250 SALESMAN
TURNER 7844 7698 1500 SALESMAN
JAMES 7900 7698 950 CLERK
CLARK 7782 7839 2450 MANAGER
MILLER 7934 7782 1300 CLERKThis show, among other things, that the employee with ename='KING' (empno=7839) has no boss.
JONES (empno=7566) does have a boss (mgr=7839), namely KING.
SCOTT (empno=7788) has a bos (mgr=7566), who is JONES.
I got the results above using this CONNECT BY query:
SELECT LPAD ( ' '
, 3 * (LEVEL - 1)
) || ename AS name
, empno
, mgr
, sal
, job
FROM scott.emp
START WITH mgr IS NULL
CONNECT BY mgr = PRIOR empno
;This is an example of a Top-Down Query , where we start with a parent, then find its children, grandchildren, and so on.
In your probelm, you want to do a Bottom-Up Query ; given a child, you want to see if its parent has a certain level of authority. If not, you need to look at that parent's parent, and keep going until to either reach someone with the right qualifications, or you reach the end of the chain of command.
That's similar to this problem: given a set of employees in scott.emp (say, everyone with job='CLERK') we want to find their closest ancestor who has a sal of 3000 or more. Look at the data above: you can see that SMITH is a CLERK, and SMITH'S boss, FORD, has sal=3000, so we want a row of output that shows SMITH and FORD.
For a different example, looks at MILLER. MILLER's boss, CLARK, only has sal=2450, so we need to look at CLARK's boss, KING.
One way to do that in a CONNECT BY query is:
SELECT CONNECT_BY_ROOT ename AS subordinate
, ename
, LEVEL - 1 AS steps_apart
FROM scott.emp
WHERE CONNECT_BY_ISLEAF = 1
START WITH job = 'CLERK'
CONNECT BY empno = PRIOR mgr
AND PRIOR sal < 3000
;Output:
SUBORDINAT ENAME STEPS_APART
SMITH FORD 1
ADAMS SCOTT 1
JAMES KING 2
MILLER KING 2You should be all set to write the query now.
Just kidding. I'll bet there's a lot of stuff in this message that's new to you. It's all documented in the SQL Language manual:
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/index.htm
If you'd like help, post your version, a more complete set of sample data, and the results you want from that data.
Explain, with specific examples, how you get the results you posted from the data you posted.
Do as much of the query as you can, and post your code. -
Help me with this tricky sql....
i need a sql querry that displays ename,salary,max(salary) such that max(salary) should be in every column.
it should be like this...
Ename Salary max(Salary)
Smith 12000 18000
robert 8000 18000
frank 14000 18000
walter 18000 18000
stacy 5000 18000
thanks
sankar..Hi, Sankar,
That's exactly what analytic functions do:
SELECT ename
, salary
, MAX (salary) OVER () AS max_salary
FROM table_x;"OVER (<analytic_clause>)" indicates that this is the analytic MAX function, not the aggregate MAX function.
You don't need an analytic clause in this case, but syntax still requires the parentheses in "OVER ()". -
Hey I'm trying to get a working understanding of some of the basics behind SQL, I've composed a few questions that I think may help me with this. Anyone that can help me with any of them will greatly help me thanks.
1. How to create synonym for tables?
2. How to describe the structure of tables?
3. How to list the contents of tables?
4. How to create a table named with the same structure as another table?
5. How to copy rows with less than a certain criteria in value (e.g. Price<$5.00) into another table?
6. How to change the data type to e.g. NUMBER(6)?
7. How to add a new column named with data type e.g. VARCHAR2(10)?
8. How to change a specific field within a table (e.g. For ORDER_NUMBER 12489, change the C_NUMBER to 315)?
9. How to delete a specific row from a table?
10. How to declare a column as the primary key of a table and call it e.g. PK_something?
11. How to show certain columns when another column is less than a certain criteria in value (e.g. Price<$5.00)?
12. How to show certain columns with another column having a certain item class e.g. HW or AP?
13. How to list certain columns when another column e.g. price is between two values?
14. How to list certain columns when another column e.g. price is negative?
15. How to use the IN operator to find certain columns (e.g. first and last name of customers who are serviced by a certain ID)
16. How to find certain columns when one of the columns begins with a particular letter (e.g. A)
18. How to list the contents of the a table sorted in ascending order of item class and, within each item class, sorted in descending order of e.g. price?
19. How to do a count of column in a table?
20. How to sum a column and make rename is something?
21. How to do a count of a column in a table (without repeats e.g. if a certain number repeats more than once than to only count it once)?
22. How to use a subquery to find certain fields in columns when the another column’s fields values are greater than e.g. its average price?848290 wrote:
Hey I'm trying to get a working understanding of some of the basics behind SQL, I've composed a few questions that I think may help me with this. Anyone that can help me with any of them will greatly help me thanks.To use the terminology you have in those questions, you must already have a basic understanding of SQL, so you have exposed yourself as not being the author of such questions.
Please do not ask homework questions without having at least attempted to answer them yourself first and show where you're struggling. -
Help with creating a sql file that will capture any database table changes.
We are in the process of creating DROP/Create tables, and using exp/imp data into the tables (the data is in flat files).
Our client is bit curious to work with. They do the alterations to their database (change the layout, change the datatype, drops tables) without our knowing. This has created a hell lot of issues with us.
Is there a way that we can create a sql script which can capture any table changes on the database, so that when the client trys to execute imp batch file, the sql file should first check to see if any changes are made. If made, then it should stop execution and give an error message.
Any help/suggestions would be highly appreciable.
Thanks,Just to clarify...
1. DDL commands are like CREATE, DROP, ALTER. (These are different than DML commands - INSERT, UPDATE, DELETE).
2. The DDL trigger is created at the database level, not on each table. You only need one DDL trigger.
3. You can choose the DDL commands for which you want the trigger to fire (probably, you'll want CREATE, DROP, ALTER, at a minimum).
4. The DDL trigger only fires when one of these DDL commands is run.
Whether you have 50 tables or 50,000 tables is not significant to performance in this context.
What's signficant is how often you'll be executing the DDL commands on which the trigger is set to fire and whether the DDL commands execute in acceptable time with the trigger in place. -
Need Help with Creating the SQl query
Hi,
SQL query gurus...
INFORMATION:
I have two table, CURRENT and PREVIOUS.(Table Defs below).
CURRENT:
Column1 - CURR_PARENT
Column2 - CURR_CHILD
Column3 - CURR_CHILD_ATTRIBUTE 1
Column4 - CURR_CHILD_ATTRIBUTE 2
Column5 - CURR_CHILD_ATTRIBUTE 3
PREVIOUS:
Column1 - PREV_PARENT
Column2 - PREV_CHILD
Column3 - PREV_CHILD_ATTRIBUTE 1
Column4 - PREV_CHILD_ATTRIBUTE 2
Column5 - PREV_CHILD_ATTRIBUTE 3
PROBLEM STATEMENT
Here the columns 3 to 5 are the attributes of the Child. Lets assume that I have two loads, One Today which goes to the CURRENT table and one yesterday which goes to the PREVIOUS table. Between these two loads there is a CHANGE in the value for Columns either 3/4/5 or all of them(doesnt matter if one or all).
I want to determine what properties for the child have changed with the help of a MOST efficient SQL query.(PARENT+CHILD is unique key). The Database is ofcourse ORACLE.
Please help.
Regards,
ParagHi,
The last message was not posted by the same user_name that started the thread.
Please don't do that: it's confusing.
Earlier replies give you the information you want, with one row of output (maximum) per row in current_tbl. There may be 1, 2 or 3 changes on a row.
You just have to unpivot that data to get one row for every change, like this:
WITH single_row AS
SELECT c.curr_parent
, c.curr_child
, c.curr_child_attribute1
, c.curr_child_attribute2
, c.curr_child_attribute3
, DECODE (c.curr_child_attribute1, p.prev_child_attribute1, 0, 1) AS diff1
, DECODE (c.curr_child_attribute2, p.prev_child_attribute2, 0, 2) AS diff2
, DECODE (c.curr_child_attribute3, p.prev_child_attribute3, 0, 3) AS diff3
FROM current_tbl c
JOIN previous_tbl p ON c.curr_parent = p.prev_parent
AND c.curr_child = p.prev_child
WHERE c.curr_child_attribute1 != p.prev_child_attribute1
OR c.curr_child_attribute2 != p.prev_child_attribute2
OR c.curr_child_attribute3 != p.prev_child_attribute3
, cntr AS
SELECT LEVEL AS n
FROM dual
CONNECT BY LEVEL <= 3
SELECT s.curr_parent AS parent
, s.curr_child AS child
, CASE c.n
WHEN 1 THEN s.curr_child_attribute1
WHEN 2 THEN s.curr_child_attribute2
WHEN 3 THEN s.curr_child_attribute3
END AS attribute
, c.n AS attribute_value
FROM single_row s
JOIN cntr c ON c.n IN ( s.diff1
, s.diff2
, s.diff3
ORDER BY attribute_value
, parent
, child
; -
Please help with dynamic pl/sql
Trying to write a generic pl/sql package that can be used on any table I specify at runtime. The procedures are simple and there are only two. I don't understand advanced pl/sql enought to write it myself dynamically. Could someone please give me ideas on this? Because I don't know the syntax of dynamic pl/sql, books aren't helping much with a project I have due tomorrow :)
Yes, it will all be done at the same time, but I would like them to be able to run independent of each other in case i want one and not the other and vice versa. In procedure 1, the only thing to be done is to get the text in column_1 of tableA to column_1 in tableB.
I have a regular procedure for procedure 1 that I think will work:
CREATE OR REPLACE PROCEDURE UPDATE_COLUMN_1
IS
v_column_1 tableB.column_1%TYPE;
v_name tableC.name%TYPE;
CURSOR c_name_column_1 IS
SELECT column_1, name from tableA;
BEGIN
OPEN c_name_column_1;
LOOP
Fetch c_name_column_1 INTO v_column_1, v_name;
EXIT WHEN c_name_column_1%NOTFOUND;
UPDATE tableB
SET column_1 = v_column_1,
lst_updt = sysdate,
updt_by = 'anna'
WHERE name = v_name;
END LOOP;
CLOSE c_name_column_1;
END UPDATE_COLUMN_1;
My main email is in my husband's name. I will get it faster than my hotmail account. [email protected] -
Help with Oracle PL/SQL and Objects...
Hi,
I wonder if you can help me, I am having some trouble dealing with Oracle objects in PL/SQL. I can declare them, populate them and read from them without any issues.
But I am having some problems with trying to copy records in to other records of the same type, and also with updating existing records. I've made a mock up piece of code below to explain what I mean, it may have a few mistakes as I've written it in notepad but should be reasonably clear.
First I have created a record type, which contains attributes relating to a person.....
CREATE OR REPLACE
TYPE PERSON_RECORD_TYPE AS object (
Person_ID NUMBER(3),
Person_Name VARCHAR(20),
Person_Age NUMBER(2),
static function new return PERSON_RECORD_TYPE );
CREATE OR REPLACE
TYPE BODY PERSON_RECORD_TYPE as
static function new return PERSON_RECORD_TYPE is
BEGIN
return PERSON_RECORD_TYPE (
NULL,
NULL,
NULL,
NULL,
NULL
END;
END;
Then I have created a table type, which is a table of the person record type......
CREATE OR REPLACE
type PERSON_TABLE_TYPE as table of PERSON_RECORD_TYPE;
Finally I have created a procedure which recieves an instance of the person table type and reads through it using a cursor.....
PROCEDURE ADMIN_PERSON (incoming_person IN PERSON_TABLE_TYPE)
IS
-- This is a local record declared as the same type as the incoming object
local_person PERSON_TABLE_TYPE;
-- Cursor to select all from the incoming object
CURSOR select_person
IS
SELECT *
FROM TABLE ( cast (incoming_person AS PERSON_TABLE_TYPE));
BEGIN
-- Loop to process cursor results
FOR select_person_rec IN select_person
LOOP
/* Up to this point works fine...*/
-- If I want to store the current cursor record in a local record of the same type, I can do this....
local_person.person_id := select_person_rec.person_id;
local_person.person_name := select_person_rec.person_name;
local_person.person_age := select_person_rec.person_age;
-- QUESTION 1
-- The above works fine, but in my real example there are a lot more fields
-- Why cant I set the local record to the value of the cursor record like this below..
local_person := select_person_rec;
-- The above line gives a pl/sql error - expression is of wrong type, (as far as I can see the records are of the same type?)
-- QUESTION 2
--Also how do you update an existing record within the original object, I have tried the following but it does not work
UPDATE incoming_person
SET age = (age + 1)
WHERE incoming_person.person_id = '123';
-- The error here is that the table does not exist
END LOOP;
END;
So I hope that you can see from this, I have two problems. The first is that I can store the current cursor record in a local record if I assign each attribute one at a time, but my real example has a large number of attributes. So why can't I just assign the entire cursor record to the local cursor record?
I get a PL/SQL error "Expression is of wrong type" when I try to do this.
The second question is with regards to the update statement, obviously this doesn't work, it expects a table name here instead. So can anyone show me how I should update existing person records in the incoming table type to the procedure?
I hope this makes sense, but I don't think I have explained it very well!!
Any help will be gratefully recieved!!
ThanksI understand why you are having trouble - my own brain started to hurt looking at your questions :)
First off, database types are not records. They can act like records but are "objects" with different characterstics.
You can create a record in PL/SQL but the "type" is of RECORD. You created an OBJECT as BODY_PERSON_RECORD_TYPE.
I don't use database types unless I really need them, such as for working with pipelined functions.
-- QUESTION 1
-- The above works fine, but in my real example there are a lot more fields
-- Why cant I set the local record to the value of the cursor record like this below..
local_person := select_person_rec; local_person is set to the (misnamed) BODY_PERSON_RECORD_TYPE, while SELECT_PERSON_REC is anchored to the cursor and is a RECORD of SELECT_PERSON%ROWTYPE with a field for each column selected in the query. Different types, not compatible.
You should be able to manually assign the object items one by one as object.attribute := record.field one field at a time.
-- QUESTION 2
--Also how do you update an existing record within the original object, I have tried the following but it does not workCheck the on-line documentation for the syntax. You'll probably have to reference the actual value through the table; this is one reason why I don't work with nested tables - the syntax to do things like updates is much more complex. -
Help with simple PL/SQL package
Hi, I'm trying to create a simple PL/SQL package to loop over a list of names and do some fuzzy pattern matching to attempt to clean up the data. Unfortunately..I don't know anything about PL/SQL, and hitting problems getting this to work. Could someone lend a hand?
p.s.
table TMP_UTL_MATCH_INPUT has a list of names to attempt matching in column called CLEAN_MERCHANT
table TMP_UTL_MATCH_OUTPUT should hold the original input row # and value, a matching output row # and value, and calculated edit_distance and jaro_winkler similaritise
table TMP_UTL_MATCH_STATUS is simply updated after each value so I can track how far in the process it's gotten (I suspect this algorithm will take a long time....)
Thanks in advance for any help!
Scott
create or replace
PROCEDURE "PROCESS_UTL_MATCH_DATA"("START_ROW" IN INTEGER DEFAULT 1) IS
--initialize variables here
num_rows integer;
edit_distance_similarity number;
jaro_distance_similarity number;
-- main body
BEGIN
select count(*) into num_rows from tmp_utl_match_input;
declare name_array as varray(num_rows) of varchar2(40);
select clean_merchant into name_array from TMP_UTL_MATCH_INPUT;
truncate table tmp_utl_match_status;
insert into tmp_utl_match_status values (0);
FOR i in 1..num_rows-1 LOOP
FOR j IN i+1..num_rows LOOP
edit_distance_similarity = utl_match.edit_distance_similarity(name_array(i), name_array(j));
jaro_winkler_similarity = utl_match.jaro_winkler_similarity(name_array(i), name_array(j);
if (edit_distance_similarity > 50 or jaro_winkler_similarity > 50)
then
insert into tmp_utl_match_output values (i, name_array(i), j, name_array(j), edit_distance_similarity, jaro_winkler_similarity);
END IF;
END LOOP;
update tmp_utl_match_status set current_row_num = i;
commit;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL; -- enter any exception code here
END;If you would not defeat Oracle's ability to tell you what errors the procedure may raise, it could help you debug this easier. Do that by deleting or commenting out the EXCEPTION.
Another issue I see is you're trying to call a DDL statement directly. You cannot truncate a table directly. Instead you need to use EXECUTE IMMEDIATE.
Another issue I see is you have a DECLARE statement that has statements following it that are not declarations. Once your declarations are done, you need a BEGIN followed by code followed by END. Either that, or put your "name_array as varray(num_rows) of varchar2(40);" statement above your BEGIN.
It would also help to list your version of Oracle, and any errors you've received so far. Arm us with the same information you have, it makes it easier for us to help you.
Plus, put \ tags around your code, that will preserve the formatting.
Such as:
SELECT column1,
column2,
column3
FROM some_table
WHERE column1 > 1000
AND column2 IS NOT NULL:
as opposed to:SELECT column1,
column2,
column3
FROM some_table
WHERE column1 > 1000
AND column2 IS NOT NULL:
Edited by: Starlight Rider on May 5, 2011 1:04 PM -
Continuation-Please help with a complex sql query
Hi all,
Thanks a lot for your suggestions and inputs in the last thread of this post.
With the help of your suggested approach,i went ahead and was able to get some more data in the format as needed..I worked on gradually adding one table after another exactly as the data is required stepwise.But,still I am facing issues with displaying them.
there are many issues I am not able to do and would appreciate if you please have a look at my latest modified SELECT given below and help me writing it to get the display as needed.
Below,is the attempted query i tried out using your inputs.But,am stuck and need your help in writing it.
**Here,there is 1 ->MANY lines for the t_objective_id--->This has many learning_record_ids which i want to group by the unique objective_id.
Also,prior to that,there is a tplan_id---->which has MANY t_objective_id's
SELECT DECODE (LAG (firstname, 1, 0) OVER (ORDER BY firstname),
firstname, ' ',
firstname
) firstname,
DECODE (LAG (emplid, 1, 0) OVER (ORDER BY emplid),
emplid, ' ',
emplid
) emplid,
DECODE (LAG (tplan_name, 1, 0) OVER (ORDER BY tplan_name),
tplan_name, ' ',
tplan_name
) tplan_name,
tplan_id,
DECODE (LAG (activities, 1, 0) OVER (ORDER BY activities),
activities, ' ',
activities
) activities,
activities,
--activities,
DECODE (LAG (t_objective_id, 1, 0) OVER (ORDER BY t_objective_id),
t_objective_id, ' ',
t_objective_id
) t_objective_id,
completed_activities,required_credits,
DECODE (LAG (learning_record_id, 1, 0) OVER (ORDER BY learning_record_id),
learning_record_id, ' ',
learning_record_id
) learning_record_id,
catalog_item_name,catalog_item_type
FROM (SELECT test_cp.firstname, test_op.emplid, tp.tplan_name,tp.tplan_id,FN_TP_GET_CMPLTD_ACT_CNT(tp.tplan_id,test_lp.lp_person_id,'1862') activities,
test_tpo.t_objective_id,
( fn_tp_obj_comp_req_act_cdt (test_lp.lp_person_id,
tp.tplan_id,
test_tpo.t_objective_id,
tp.is_credit_based
+ fn_tp_obj_comp_opt_act_cdt (test_lp.lp_person_id,
tp.tplan_id,
test_tpo.t_objective_id,
tp.is_credit_based
) completed_activities,test_tpo.required_credits,lr.learning_record_id,lr.catalog_item_name,lr.catalog_item_type
FROM test_learning_plan test_lp,
test_training_plan tp,
test_person test_cp,
test_org_person test_op,test_tp_learning_activity test_tplplr,
test_tp_objective test_tpo,test_learning_record lr,test_train_obj_activity tpobjact
WHERE test_lp.lp_person_id = '1862188559'
AND test_cp.person_id = test_lp.lp_person_id
AND tp.tplan_id = 'tplan200811200632352287621599'
AND test_tpo.t_objective_id = tpobjact.t_objective_id
AND test_lp.LP_CATALOG_HIST_ID = tp.tplan_id
AND test_tplplr.tp_lp_lr_id =test_lp.learning_plan_id
AND test_tplplr.activity_lp_lr_id = lr.learning_record_id
AND lr.LR_CATALOG_HISTORY_ID = tpobjact.activity_id
AND test_op.o_person_id = test_cp.person_id
AND test_tpo.tplan_id = tp.tplan_id)
If we see the outer SELECT ---then one of the main issues is for EACH t_objective_id----->There are n learning_record_ids.
But,this select only shows 1 learning_record_id for each objective_id which is wrong.
Similarly,the data displayed isnot proper.
Below is the way I am getting the data now from the above SELECT.
Note:- FIRSTNAME is not correctly displayed.
FIRSTNAME EMPLID TPLAN_NAME TPLAN_ID ACTIVITIES ACTIVITIES_1
001 TP1 tplan1 5 5
TESTNAME tplan1 5
Continuation of the other columns of the same rows--**couldnt paste it properly so.
T_OBJECTIVE_ID COMPLETED_ACTIVITIES REQUIRED_CREDITS LEARNING_RECORD_ID CATALOG_ITEM_NAME CATALOG_ITEM_TYPE
obj1 1 5 lr1 C1 Course
obj2 4 4Something like this might solve your problem ->
satyaki>
satyaki>select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
Elapsed: 00:00:00.00
satyaki>
satyaki>
satyaki>select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7521 WARD SALESMAN 7698 22-FEB-81 226.88 500 30
7654 MARTIN SALESMAN 7698 28-SEP-81 1815 1400 30
7788 SCOTT ANALYST 7566 19-APR-87 598.95 20
7839 KING PRESIDENT 17-NOV-81 7260 10
7844 TURNER SALESMAN 7698 08-SEP-81 2178 0 30
7876 ADAMS CLERK 7788 23-MAY-87 159.72 20
7900 JAMES CLERK 7698 03-DEC-81 1379.4 30
7902 FORD ANALYST 7566 03-DEC-81 5270.76 20
7934 MILLER CLERK 7782 23-JAN-82 1887.6 10
7566 Smith Manager 7839 23-JAN-82 1848 0 10
7698 Glen Manager 7839 23-JAN-82 1848 0 10
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7599 BILLY ANALYST 7566 10-JUN-09 4500 30
12 rows selected.
Elapsed: 00:00:00.00
satyaki>
satyaki>
satyaki>
satyaki>
satyaki>select decode(lag(job,1,null) over(order by job),'CLERK','CK',
2 'SALESMAN', 'SM',
3 'ANALYST','AL',
4 'BO') res
5 from emp;
RE
BO
AL
AL
AL
CK
CK
CK
BO
BO
BO
SM
RE
SM
12 rows selected.
Elapsed: 00:00:00.01
satyaki>
satyaki>
satyaki>select MAX(decode(lag(job,1,null) over(order by job),'CLERK','CK',
2 'SALESMAN', 'SM',
3 'ANALYST','AL',
4 'BO')) res
5 from emp;
select MAX(decode(lag(job,1,null) over(order by job),'CLERK','CK',
ERROR at line 1:
ORA-30483: window functions are not allowed here
Elapsed: 00:00:00.01
satyaki>
satyaki>select MAX(res)
2 from (
3 select decode(lag(job,1,null) over(order by job),'CLERK','CK',
4 'SALESMAN', 'SM',
5 'ANALYST','AL',
6 'BO') res
7 from emp
8 );
MA
SM
Elapsed: 00:00:00.00
satyaki>
satyaki>Regards.
Satyaki De. -
Help with a advanced SQL query
I have a table with the help of standard lengths of material. (tblStdLength)
In another table are the lengths that are in stock at the material. (tblOnStock)
I would want to match these two tables to find out how much of the stock of standard lengths you have in stock the table.
If the length is longer than the nearest standard length, the drag of the excess down to the nearest standradlängd if there is an X "CUT field.
However, I have encountered a problem and can not solve this ...
Ex:
Material Cable23 have 4 standard lengths in Table tblStdLength:
{code}
Material StdLength
Cable23 | 2000
Cable23 | 4000
Cable23 | 6000
Cable23 | 8000
Materials Cable23 have the following lengths in stock in Table tblOnStock:
Material Factor Length TotalQty Cut
Cable23 | 1 | 383 | 383 |
Cable23 | 1 | 424 | 424 |
Cable23 | 1 | 998 | 998 |
Cable23 | 1 | 1000 | 1000 |
Cable23 | 3 | 4000 | 12000 | X
Cable23 | 1 | 4234 | 4234 | X
{code}
In this mode, shall the lengths of 12000 + 4000 include in the calculation of the total stock of standard lengths.
The answer should be 16000.
4000, it gets of 4234. It has X on the 'Cut' field and then it round down to the nearest standard length.
How do I do this best? Hope I explained so you understand ...Hi again,
SQL works great when there are several lengths (rows) in the table tblStdlength. But sometimes there is only one standard length per matrial in the table (1 row), then it does not work. Why? Assumes lead function that there should be several rows?
with tblStd as
select Material
, stdlength
, lead(stdlength) over (partition by material order by stdlength) hstdlength
from tblStdlength
select t.Material
, sum(floor(s.total_qty/t.stdlength)*t.stdlength) tot_quantity
from tblStd t, tblonstock s
where t.material=s.material
and s.length >= t.stdlength
and s.length< t.hstdlength
group by t.material -
I am having following records
A,B,C,1
A,B,C,2
A,B,C,3
P,Q,R,1
X,Y,Z,1
M,N,O,1
I,J,K,1
I,J,K,9
L,M,N,1
Now my select statement should give me the following result
P,Q,R,1
X,Y,Z,1
M,N,O,1
L,M,N,1
Basically I need those records where the fourth field should have only 1 and shouldn't have any other value. Here all the fields are Key Fields.
Please help me in getting the result.
Nothing is striking me as I am writing SQL after long gap
Thanking you in advance.Or the same idea as Gabe's, but using analytic function:
SQL> with d as
2 ( select 'A' c1,'B' c2,'C' c3, 1 c4 from dual union all
3 select 'A' ,'B' ,'C' , 2 from dual union all
4 select 'A' ,'B' ,'C' , 3 from dual union all
5 select 'P' ,'Q' ,'R' , 1 from dual union all
6 select 'X' ,'Y' ,'Z' , 1 from dual union all
7 select 'M' ,'N' ,'O' , 1 from dual union all
8 select 'I' ,'J' ,'K' , 1 from dual union all
9 select 'I' ,'J' ,'K' , 9 from dual union all
10 select 'L' ,'M' ,'N' , 1 from dual
11 )
12 select c1, c2, c3, c4
13 from (select d.*, count(*) over(partition by c1, c2, c3) cnt from d)
14 where c4 = 1
15 and cnt = 1
16 /
C1 C2 C3 C4
L M N 1
M N O 1
P Q R 1
X Y Z 1 -
Need Help with Formula using SQL maybe
I need help! I work with Crystal reports XI and usually manage just fine with the Formula editor but his one I think will require some SQL and I am not good at that.
We are running SQL 2000 I think (Enterprise Manager 8.0) Our sales people schedule activities and enter notes for customer accounts. Each is stored in a separate table. I need to find activities that are scheduled 240 days into the future and show the most recent note that goes with the account for which that activity is scheduled.
The two tables, Activities and History, share the an accountID field in common that links them to the correct customer account. I want to look at dates in the Startdate.Activities field more than 240 days in the future and show the most recent note from the History table where the accountid's match. I figure my query will contain a join on AccountID.Activities and AccountID.History used with Max(completedate.History) but I do not understand how to word it.
I would like to perform all this in crystal if possible. I humbly request your help.
MemberyYou SQL would look something like this...
SELECT
a.AccountID,
a.BlahBlahBlah, -- Any other fields you want from the Activities table
h.LastComment
FROM Activities AS a
LEFT OUTER JOIN History AS h ON a.AccountID = h.AccountID
WHERE (a.ActivityDate BETWEEN GetDate() AND DateAdd(dd, 240, GetDate()))
AND h.HistoryID IN (
SELECT MAX(HistoryID)
FROM History
GROUP BY AccountID)
This method assumes that the History table has a HistoryID that increments up automatically each time a new comment is added... So a comment made today would always have a higher HistoryID that one made yesterday.
If I'm wrong and there is no HistoryID or the HistoryID doesn't increment in a chronological fashion, it can still be done but the code is a bit more complex.
HTH,
Jason
Maybe you are looking for
-
Problems drawing images form another class
Ok as the title says I'm having trouble drawing images from a different class. I have a class that represents a plane and it has a draw' method that draws its .gif image. public void draw (Graphics g) g.drawImage(planepic , xPos, yPos, null) then in
-
How to set an icon for a JLabel with Advanced Synth
Hello, Do you know how to define an icon for a JLabel components with Advanced Synth (with a XML file) ? I have tried this : <style id="jLabelNotes"> <imageIcon id="iconNotes" path="images/note.png" /> <property key="Label.icon" value
-
Send to Speedgrade dpx workflow only converts about half of the timeline
I am using RED footage (and some QT stock) and sending this footage from Premiere CC to Speedgrade using dpx files. (I can't use EDL because of multiple resizes/reframes throughout the project, so please don't consider that as an option) I have split
-
Hi I am evaluating Edge after reviewing Cloud & Lumira Server. Currently, Edge refresh based on MS SQL Server 2008 and 2012 and is not available for BO Universe. For BO, I will have to use SAP Lumira server and not Edge. Will this change in later ver
-
Mini shuts down just after start up
Any advice would be appreciated. My mini seems to start up OK (chime, light, no flashing) but after a few seconds, it shuts down. The monitor never has a chance to come on. After repeatingly trying to turn it on, it eventually does come on with no vi