Finding all rows based on previous rows column value diffrence
I have an interesting requirement. There is a DATE column and a user in a table and I have to find all rows for all the user for which the previous row and current row has time difference of lets say more than 30 minutes. Rows are already sorted by time.
For example in the following table, we need ID 4 and 6 for user 1.
ID User date
1 1 today 1 hour 0 min 0 s
2 1 today 1 hour 1 min 0 s
3 1 today 1 hour 29 min 0 s
*4 1 today 1 hour 59 min 3 s*
5 1 today 2 hour 10 min 2 s
*6 1 today 2 hour 50 min 7 s*
Edited by: user733179 on Mar 5, 2009 12:00 PM
Hi,
To get all the users in the result set, outer-join to a table (or subquery, as shown bleow) that has one row per user:
WITH got_dif AS
SELECT id, dt, usr
, (dt - LAG (dt)
OVER ( PARTITION BY usr
ORDER BY dt
) -- difference in days
* 24 * 60 AS minutes_dif
FROM table_x
-- WHERE ... -- if needed
, all_users AS
SELECT DISTINCT usr
FROM table_x
SELECT gd.id, gd.dt, au.usr
, NVL2 ( gd.usr
, 'Okay'
, 'Dif is never > 30'
) AS flag
FROM all_users
LEFT OUTER JOIN got_dif ON gd.usr = au.usr
AND gd.minutes_dif > 30
;Notice that the test for a 30-minute difference is part of the join condition.
You don't need the flag column, and you may not want it.
If you would prefer a separate query of just the users that are not in the original result set, then you can use the original query (modified only slightly) as an EXISTS ior NOT IN sub-query. For example:
SELECT DISTINCT usr
FROM table_x
WHERE usr NOT IN
WITH got_dif AS
SELECT id, dt, usr
, (dt - LAG (dt)
OVER ( PARTITION BY usr
ORDER BY dt
) -- difference in days
* 24 * 60 AS minutes_dif
FROM table_x
-- WHERE ... -- if needed
SELECT usr -- Only 1 column in SELECT clause
FROM got_dif
WHERE minutes_dif > 30
;
Similar Messages
-
Add row based on previous row in table control?
Dear all,
I have a table control with some rows. Every row contains one button. On button click i want to add another row with dirrerent data. I want to add content based on button text or another columns (ex text views text,) based on this text view, I have to add row. One button can click any no of times. On every click i want to add row, but desired position and content should be based on button click. Any help in doing this??
Cheers,
Venkys.Refer to these old threads referring this table and button problem.
Adding rows to table
How to create different rows in table or in ALV?
and for the current scenario what you can do is ...
in the eventhandler of the button click .
find out the row number by using the code to read index.
then based upon that add the element in the node at the desired position.
finding the row number
data indx type i.
DATA lo_el TYPE REF TO if_wd_context_element.
lo_el = wdevent->get_context_element( 'CONTEXT_ELEMENT' ).
indx = lo_el->get_index( ).
and the adding the element at the desired position say n
DATA lo_nd_zdealer TYPE REF TO if_wd_context_node.
lo_nd_zdealer = wd_context->get_child_node( name = 'DEALER' ).
data ls_str type wd_this->element_dealer.
ls_str-id = '00023445'.
ls_str-name = 'sarbjeet'.
ls_str-location = 'hosiarpur'.
ls_str-status = '0001'.
lo_nd_zdealer->bind_structure( new_item = ls_str
set_initial_elements = abap_false
index = n
thanks
sarbjeet singh -
Analytical function need to work based on previous rows result.
My data are sorted based on sartdatetime column.but i need the sum(value) based on below condition.
Condition :
i need to check with current row with previous rows
if they are same then i need to sum the value with previous row.
else i need to start the summation.
My data like below:
Rownum Code Sartdatetime Value
1 4619 12/9/2012 11:00 219
2 5344 12/9/2012 14:39 27
3 4619 12/9/2012 15:11 20
4 4619 12/9/2012 19:33 14
5 4619 12/9/2012 20:53 16
6 6851 12/9/2012 21:21 1
7 4619 12/9/2012 21:22 35
8 5623 12/10/2012 1:59 4
9 5623 12/10/2012 2:03 3
10 5623 12/10/2012 2:06 5
11 4619 12/10/2012 2:17 1
12 5623 12/10/2012 2:18 5
13 5623 12/10/2012 2:25 2
14 5623 12/10/2012 2:27 2
15 4619 12/10/2012 2:29 30
Eg:
Take the first row. For that no previous rows. So we directly added the value like below.
Rownum Code Sartdatetime Value sum(val)
1 4619 12/9/2012 11:00 219 219
take the seconds row, we can check the code value (5344)with first row value (4619). the values are different . So our summation like.
2 5344 12/9/2012 14:39 27 27
for third row , we can check the code value (4619)with second row value (5344). the values are different . So our summation like.
3 4619 12/9/2012 15:11 20 20
for fourth row we can check the code value (4619)with second row value (4619). the values are same. So our summation like.
4 4619 12/9/2012 19:33 14 34 - The sum of previous row result.
5 th row also same value so
5 4619 12/9/2012 20:53 16 50T he sum of previous row result.
then the same value come again in 7 th row so here we need to start the summation like below.
7 4619 12/9/2012 21:22 35 35.
i want the result like below.
Rownum Code Sartdate time Value Expected result
1 4619 12/9/2012 11:00 219 219
2 5344 12/9/2012 14:39 27 27
3 4619 12/9/2012 15:11 20 20
4 4619 12/9/2012 19:33 14 34
5 4619 12/9/2012 20:53 16 50
6 6851 12/9/2012 21:21 1 1
7 4619 12/9/2012 21:22 35 35
8 5623 12/10/2012 1:59 4 4
9 5623 12/10/2012 2:03 3 7
10 5623 12/10/2012 2:06 5 12
11 4619 12/10/2012 2:17 1 1
12 5623 12/10/2012 2:18 5 5
13 5623 12/10/2012 2:25 2 7
14 5623 12/10/2012 2:27 2 9
15 4619 12/10/2012 2:29 30 30
Please helpHi,
Welcome to the forum!
Here's one way to do what you want:
WITH got_grp_id AS
SELECT code, starttime, value
, ROW_NUMBER () OVER ( ORDER BY starttime ) AS r_num
, ROW_NUMBER () OVER ( ORDER BY starttime )
- ROW_NUMBER () OVER ( PARTITION BY code
ORDER BY starttime
) AS grp_id
FROM table_x
SELECT r_num
, code
, starttime
, value
, SUM (value) OVER ( PARTITION BY code, grp_id
ORDER BY starttime
) AS sum_value
FROM got_grp_id
ORDER BY starttime
;For an explanation of the Fixed Difference technique, see {message:id=9953384} and/or {message:id=9957164}
Whenever you have a problem, please post CREATE TABLE and INSERT statements for your same data. For example:
CREATE TABLE table_x
( code NUMBER (4)
, starttime DATE UNIQUE
, value NUMBER
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/9/2012 11:00', 'MM/DD/YYYY HH24:MI'),
219);
INSERT INTO table_x (code, starttime, value)
VALUES (5344, TO_DATE ( '12/9/2012 14:39', 'MM/DD/YYYY HH24:MI'),
27);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/9/2012 15:11', 'MM/DD/YYYY HH24:MI'),
20);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/9/2012 19:33', 'MM/DD/YYYY HH24:MI'),
14);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/9/2012 20:53', 'MM/DD/YYYY HH24:MI'),
16);
INSERT INTO table_x (code, starttime, value)
VALUES (6851, TO_DATE ( '12/9/2012 21:21', 'MM/DD/YYYY HH24:MI'),
1);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/9/2012 21:22', 'MM/DD/YYYY HH24:MI'),
35);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ( '12/10/2012 1:59', 'MM/DD/YYYY HH24:MI'),
4);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ('12/10/2012 2:03' , 'MM/DD/YYYY HH24:MI' ),
3);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ( '12/10/2012 2:06', 'MM/DD/YYYY HH24:MI'),
5);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/10/2012 2:17', 'MM/DD/YYYY HH24:MI'),
1);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ( '12/10/2012 2:18', 'MM/DD/YYYY HH24:MI'),
5);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ( '12/10/2012 2:25', 'MM/DD/YYYY HH24:MI'),
2);
INSERT INTO table_x (code, starttime, value)
VALUES (5623, TO_DATE ('12/10/2012 2:27' , 'MM/DD/YYYY HH24:MI' ),
2);
INSERT INTO table_x (code, starttime, value)
VALUES (4619, TO_DATE ( '12/10/2012 2:29', 'MM/DD/YYYY HH24:MI'),
30);
COMMIT; See the forum FAQ {message:id=9360002}
Output:
R_NUM CODE STARTTIME VALUE SUM_VALUE
1 4619 12/9/2012 11:00 219 219
2 5344 12/9/2012 14:39 27 27
3 4619 12/9/2012 15:11 20 20
4 4619 12/9/2012 19:33 14 34
5 4619 12/9/2012 20:53 16 50
6 6851 12/9/2012 21:21 1 1
7 4619 12/9/2012 21:22 35 35
8 5623 12/10/2012 01:59 4 4
9 5623 12/10/2012 02:03 3 7
10 5623 12/10/2012 02:06 5 12
11 4619 12/10/2012 02:17 1 1
12 5623 12/10/2012 02:18 5 5
13 5623 12/10/2012 02:25 2 7
14 5623 12/10/2012 02:27 2 9
15 4619 12/10/2012 02:29 30 30Edited by: Frank Kulash on Dec 24, 2012 6:44 AM
Added sample data. -
Trying to use ALL_TAB_COLS to find two tables based on input rows
I'm using 9i.
I'm trying to use the ALL_TAB_COLS table to find two tables that contain columns I can join them on. I know the names of the two tables. We can call them table1 and table2. I just using the columns that are stored in them below to find a common set of tables.
The query I'm using is the following
select distinct did.TABLE_NAME, did.COLUMN_NAME
from
(Select * from ALL_TAB_COLS
where column_name in('SO_LINE_ID','SO_LINE_NUMBER', 'SO_ORDER_NUMBER', 'SO_HEADER_ID','AR_CUSTOMER_TRX_LINE_ID')
--and OWNER = 'FTBV'
) did
join
(Select * from ALL_TAB_COLS
where column_name in('SCHED_DISTRIBUTION_ID', 'CODE_COMBINATION_ID', 'PRODUCT_BUSINESS_CODE', 'PRODUCT_GROUP_CODE', 'PRODUCT_CODE')
--and OWNER = 'FTBV'
) iii
on did.TABLE_NAME = iii.TABLE_NAME;It's giving me limited results.
What I need is something that can find interim tables that would link my two tables together based on the unique columns I've provided. Does such a query exist?
Thanks in Advance.Only if there is a defined foreign key relationship. If there is one the queries you want are on the Constraints page of Morgan's Library at www.psoug.org. If they do not exist then you need to find a subject matter expert that can explain the application's design.
The fact that you are asking this question is a strong indication of a lack of proper documentation at your facility: Something you might wish to address. -
Adding a Multiple Rows Without Clearing Previous Row Details
Dear All,
I want to Add multiple rows at the same time in a matrix at the same time .My problem here is When i add the New rows to the matrix already added data need to remail in the matrix , I cant put Matrix.Clear or Datasource.clear.
When i add multiple rows previous row details is duplicated to next rows how to avoid thus
MohamedHi,
try this,
If (pVal.ItemUID = "BTNUID") And (pVal.EventType = SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED) Then
Dim fr As SAPbouiCOM.Form
Dim sel As Integer
Dim oMatrix1 As SAPbouiCOM.Matrix
fr = SBO_Application.Forms.Item(FormUID)
oMatrix1 = fr.Items.Item("mtx_136").Specific
fr.DataSources.DBDataSources.Item(2).Clear()
sel = oMatrix1.GetNextSelectedRow
oMatrix1.AddRow(1, sel)
End If
"mtx_136" is your matrix ID
and "BTNUID" is your button ID -
My old computer fried and died. How can i find all the songs I previously downloaded?
I lost all the data on my old hard drive. I downloaded the newest version of i tunes for my new computer. Now how can i re download all the songs I previously purchased? Thanks for helping
It has always been very basic to always maintain a backup copy of your computer for just such an occasion. us eyour backup copy to put everything back.
If for some reason you have failed to backup, then you can transfer itunes purchases from an ipod: File>Transfer Purchases.
In the U.S you can use icloud. Open itunes store, click Purchased under Quick Links. -
How to find the exact coloumn which fired the column value too large error
Hi all
I have a procedure which has a insert statement init.
I have encountered an column value too large error in that procedure.
I want to know exactly in which column the error has come
Any ideas,
Thanks
HariWhat is your insert statement? I get the exact column name here.
SQL> create table sample1(col1 number(1), col2 number(3), col3 varchar2(2))
2 /
Table created.
SQL> insert into sample1
2 select 1, 2, 'A' from dual
3 union
4 select 1,333, 'B' from dual
5 union
6 select 2, 44, 'CCC' from dual
7 /
insert into sample1
ERROR at line 1:
ORA-12899: value too large for column "ETL_USER"."SAMPLE1"."COL3" (actual: 3,
maximum: 2)
SQL> Cheers
Sarma. -
Populate other column value based on previous row value using t-sql
Hi All,
I have one table with 6 columns, let say ID1, ID2,status, EnteredDate,NewValue, Old Value. Where ID1 is the primary key field
ID1 ID2 status EnteredDate NewValue
Old Value
1 XYZ New 07/12/2012
ABC null
2 XYZ Renewal 08/19/2012 DEF
null
3 XYZ Cancel 10/21/2012 GHI
null
4 ZYX New 09/15/2012
BDF null
5 ZYX Cancel 10/21/2012 MNS
null
6 MBS New 05/29/2012
EXP null
7 SBX New 05/29/2012
SKS null
8 SBX Renewal 06/21/2012 QSR
SKS
Basically I need a sql query which should populate Output as below. Status=New will always have old date compared to Renewal and Cancel and also OldValue field will be null always for status=New
Output:
ID1 ID2 status EnteredDate NewValue
Old Value Row_Num(based on ID1,ID2,Entereddate)
1 XYZ New 07/12/2012
ABC null 1
2 XYZ Renewal 08/19/2012 DEF
ABC 2
3 XYZ Cancel 10/21/2012 GHI
DEF 3
4 ZYX New 09/15/2012
BDF null 1
5 ZYX Cancel 10/21/2012 MNS
BDF 2
6 MBS New 05/29/2012
EXP null 1
7 SBX New 05/29/2012
SKS null 1
8 SBX Renewal 06/21/2012 QSR
SKS 2
Thanks in Advance, its very urgent. Pls send me the query ASAP.
RH
sqlHi,
In case of you are using SQL 2012, you can use new built-in function like LAG, try this;
USE tempdb
GO
CREATE TABLE dbo.Test
ID1 int PRIMARY KEY
, ID2 char(3) NOT NULL
, Status varchar(20) NOT NULL
, EnteredDate date NOT NULL
, NewValue char(3) NOT NULL
, OldValue char(3) NULL
GO
INSERT INTO dbo.Test
(ID1, ID2, Status, EnteredDate, NewValue, OldValue)
VALUES
(1, 'XYZ', 'New', '07/12/2012', 'ABC', null)
, (2, 'XYZ', 'Renewal', '08/19/2012', 'DEF', null)
, (3, 'XYZ', 'Cancel', '10/21/2012', 'GHI', null)
, (4, 'ZYX', 'New', '09/15/2012' ,'BDF', null)
, (5, 'ZYX', 'Cancel', '10/21/2012', 'MNS',null)
, (6, 'MBS', 'New', '05/29/2012', 'EXP', null)
, (7, 'SBX', 'New', '05/29/2012', 'SKS', null)
, (8, 'SBX', 'Renewal', '06/21/2012', 'QSR', 'SKS')
WITH cte
AS
(SELECT ID1, ID2, Status, EnteredDate, NewValue, OldValue
, ROW_NUMBER() OVER(PARTITION BY ID2 ORDER BY ID2) Row_Num
, LAG(NewValue, 1, 0) OVER(PARTITION BY ID2 ORDER BY ID2) NewOldValue
FROM dbo.Test)
SELECT ID1, ID2, Status, EnteredDate, NewValue
, NULLIF(NewOldValue, '0') NewOldValue, Row_Num
FROM cte
ORDER BY ID1, ID2;
Dinesh Priyankara
http://dinesql.blogspot.com/
Please use Mark as answer (Or Propose as answer) or Vote as helpful if the post is useful. -
Need help with disabling fields or hiding rows based on previous field
Hi,
I have a report in a region.
The report has five columns:
Animal type_ Health Issues* Angel Grant Requested?* Granted?* Grant Response Date*
Dog Fleas Yes Yes 02/04/2009
Cat Fleas No
The first time the screen is displayed only the Animal type_ Health Issues* Angel Grant Requested?* columns will appear.
The user will make a selection for 'Angel Grant Requested' from the LOV ('YES', 'NO') and then click on the 'Submit' button.
When the screen returns 'Angel Grant Requested?' will be grayed out so the user cannot change the selection. The user will make a selection for 'Granted?' using LOV ('YES, 'NO') and for 'Grant Response Date' using the calendar.
{color:#ff0000}{color:#0000ff}Here is what I want to do...
If the user selects 'NO' for 'Angel Grant Requested?' then I would like to do one of the following (which ever one is easiest to do) when the screen returns:
1. Disable (gray out) the 'Granted?' and 'Grant Response Date' fields on the screen for the rows that have 'NO' for 'Angel Grant Requested?'
so that the user cannot make any selection, AND update the HEALTH_ISSUES table to
set grant_granted = 'N/A'
grant_response_date = sysdate
WHERE animal_issue_type_id = AI_ID;
2. Do not display the rows that have 'NO' for 'Angel Grant Requested?'
{color}
Can you please provide code samples to do this?
{color:#ff0000}*I tried to use javascript to gray out the columns, the problem I have is with the hidden f02 column (Angel Grant Requested) that I created on the report so that javascript could read the value. columns are being disabled as desired but the database table is not updating properly...*
{color:#ff0000}*For the rows where the user selected 'YES' for 'Angel Grant Requested?' we need to update the table with the 'Granted?' and 'Grant Response Date' values. These values are somehow being put on the row where the user selected 'NO' for 'Angel Grant Requested?'.*
This happens in the UPDATE_ISSUES PL/SQL after When :P6_DSP_REQUESTED = 'DSPGRANTED'{color}
Below is the Javascript function that is in HTML HEADER:_
</script>
<script language="JavaScript1.1" type="text/javascript">
function checkAngelGrant()
var col2=document.forms[0].f02; /* angel grant requested */
var col3=document.forms[0].f03; /* angel grant granted */
var col4=document.forms[0].f04; /* grant response date */
for (i=0;i<col2.length;i++)
var col2Check = col2+.value; /* read the hidden angel grant requested field */+
+/* checks the hidden angel grant requested field+
if no then we need to disable the angel grant granted field and the angel response date field.
if (col2Check == 'NO')
+{+
col3.disabled=true; /* angel grant granted (Yes No) */
col4.disabled=true; /* angel response date
Below is the UPDATEISSUES PL/SQL process that is run on After Submit:_*
DECLARE
ai_id NUMBER;
vgrant_requested VARCHAR2(3);
vgrant_grnted VARCHAR2(3);
vgrant_respdate DATE;
f01 = Animal Issue Type ID
f02 = grant requested ('YES','NO')
F03 = grant granted ('YES','NO')
F04 = grant response date
P6_DSP_REQUESTED = DSPGRANTED display region with grant_granted and grant_respdate
P6_DSP_REQUESTED = DSPREQUESTED display region with grant_requested only
P6_DSP_REQUESTED = BIFNOCHG cannot change any of the fields that have already been set
BEGIN
IF :P6_DSP_BEQUESTED = 'DSPREQUESTED' then -- Allow setting of grant_requested value only
FOR i IN 1..HTMLDB_APPLICATION.G_F01.COUNT LOOP
ai_id := HTMLDB_APPLICATION.G_F01(i); -- animal_issue_type_id This is hidden
vgrant_requested := HTMLDB_APPLICATION.G_F02(i); -- grant_requested (YES or NO)
UPDATE HEALTH_ISSUE_TYPES
SET grant_requested = vgrant_requested
WHERE animal_issue_type_id = AI_ID;
COMMIT;
END LOOP;
elsif :P6_DSP_REQUESTED = 'DSPGRANTED' then -- grant_granted and grant_response_date
FOR i IN 1..HTMLDB_APPLICATION.G_F01.COUNT LOOP
ai_id := HTMLDB_APPLICATION.G_F01(i); -- animal_issue_type_id This is hidden
vgrant_grnted := HTMLDB_APPLICATION.G_F02(i); -- grant_granted (YES or NO)
vgrant_respdate := to_date(HTMLDB_APPLICATION.G_F03(i),'MM/DD/YYYY');
UPDATE HEALTH_ISSUE_TYPES
SET grant_granted = vgrant_grnted,
grant_response_date = vgrant_respdate
WHERE animal_issue_type_id = AI_ID;
COMMIT;
END LOOP;
end if;
END;It's actually three reports that get run during different stages of the screen.
When the user first enters the screen the data is populated from the REQUESTED REPORT sql:
SELECT hit.animal_issue_type_id, at.animal_type_desc, it.issue_type_desc, hit.grant_requested
FROM health_issue_types hit, animal_types at,issue_types it
WHERE hit.animal_type_id = at.animal_type_id
AND hit.issue_type_id = it.issue_type_id
AND hit.file_no = :P6_FILE_NO;
The user will make a selection from the LOV select list (Yes, No) for the grant_requested field and then click on the Submit button.
{color:#ff0000}*If the user selects 'NO' for this field then I want to disable the grant_granted and grant_response_date fields when the screen is populated from the ISSUES REPORT sql. If this cannot be easily done then I would like to hide the entire row when 'NO' has been selected for the grant_requested field.*{color}
When the screen returns the data is populated from the ISSUES REPORT sql:
ISSUES REPORT
SELECT hit.animal_issue_type_id, at.animal_type_desc, it.issue_type_desc, hit.grant_requested,
hit.grant_granted, hit.grant_response_date
FROM health_issue_types hit, animal_types at,issue_types it
WHERE hit.animal_type_id = at.animal_type_id
AND hit.issue_type_id = it.issue_type_id
AND hit.file_no = :P6_FILE_NO;
At this point the grant_requested field will no longer be available for user modification. The user will make a selection from the LOV select list (Yes, No) for the grant_granted, and the grant_response_date fields and then click on the Submit button again.
When the screen returns the data is populated from the ANIMAL DISPLAY ONLY REPORT sql:
ANIMAL DISPLAY ONLY REPORT
SELECT hit.animal_issue_type_id, at.animal_type_desc, it.issue_type_desc, hit.grant_requested,
hit.grant_granted, hit.grant_response_date
FROM health_issue_types hit, animal_types at, issue_types it
WHERE hit.animal_type_id = at.animal_type_id
AND hit.issue_type_id = it.issue_type_id
AND hit.file_no = :P6_FILE_NO;
At this point the grant_requested, grant_granted, and grant_response_date fields will no longer be available for user modification.
{color:#0000ff}Thank you for taking the time to look at my problem.{color} -
Query! calculation based on previous row value
Hi,
ID Code Direction From Amount To Perct To Amount
98 POI F 5457.00 0
77 LKJ T 0 50 (5457*(50/100))
56 MNB T 0 25 (5457*(25/100))How to calculate 'To Amount' with in the select query? To Amount will be calculated on the basis of
From Amount of the First row multiplied by 'To Perct'
When I wrote a select statement it's taking 0 as 'From Amount'( Because it's in current row) and giving me 0 as 'To Amount'
ThanksOne possibility:
with t as (
select 98 id, 'POI' Code, 'F' Direction, 5457.00 FromAmount, 0 ToPerct from dual union all
select 77, 'LKJ', 'T', 0, 50 from dual union all
select 56, 'MNB', 'T', 0, 25 from dual)
select id, code, direction, FromAmount, ToPerct,
(tmax.MaxAmount)*(ToPerct/100) ToAmount
from t,
(select max(FromAmount) MaxAmount from t) tmax ;Results:
ID COD D FROMAMOUNT TOPERCT TOAMOUNT
98 POI F 5457 0 0
77 LKJ T 0 50 2728,5
56 MNB T 0 25 1364,25Regards,
Miguel -
Grouping Header Rows based on common rows in Details
Hi,
I have two tables TAB_MST and TAB_DTL with information like below:
{code}
CREATE TABLE TAB_MST
MSTCOL NUMBER
ALTER TABLE TAB_MST ADD CONSTRAINT TAB_MST_PK PRIMARY KEY (MSTCOL)
INSERT INTO TAB_MST (MSTCOL) VALUES (1);
INSERT INTO TAB_MST (MSTCOL) VALUES (2);
INSERT INTO TAB_MST (MSTCOL) VALUES (3);
INSERT INTO TAB_MST (MSTCOL) VALUES (4);
CREATE TABLE TAB_DTL
MSTCOL NUMBER,
DTLCOL NUMBER
ALTER TABLE TAB_DTL ADD CONSTRAINT TAB_DTL_PK PRIMARY KEY (MSTCOL, DTLCOL)
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (1, 1);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (1, 2);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (1, 3);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (1, 4);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (1, 5);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (2, 4);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (2, 7);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (2, 8);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (2, 9);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (3, 8);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (3, 9);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (3, 10);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (3, 11);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (4, 12);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (4, 13);
INSERT INTO TAB_DTL (MSTCOL, DTLCOL) VALUES (4, 14);
COMMIT;
{code}
I want to group rows in Master table (TAB_MST) to different groups based on the data in detail table (TAB_DTL) with output as below
MSTCOL GROUPID
1 1
2 1
3 1
4 2
Rule for Grouping are as follows:
1) If there is any common value of DTLCOL for two different values of MSTCOL, then both MSTCOL values should be grouped under same group, e.g. for above sample case
DTLCOL (Value = 4) is common for MSTCOL = 1 and MSTCOL = 2, hence MSTCOL 1 and MSTCOL 2 belong to same group (GROUPID = 1).
DTLCOL (Value = 8, 9) is common for MSTCOL = 2 and MSTCOL = 3, hence MSTCOL 3 should belong to same group as MSTCOL 2 (GROUPID = 1)
There is no common value of DTLCOL for MSTCOL = 4, hence it is in a separate group.
Below is the sample PL/SQL block to highlight this grouping behavior. Two temporary tables are created to achieve this:
{code}
CREATE TABLE TAB_MST_GROUP
MSTCOL NUMBER,
GROUPID NUMBER
CREATE TABLE TAB_TMP_GROUP
GROUPID NUMBER
DECLARE
CURSOR c1
IS
SELECT * FROM tab_mst;
prevmstcol NUMBER;
prevgroupid NUMBER := 1;
vtmpgroupid NUMBER;
BEGIN
DELETE tab_mst_group;
FOR r1 IN c1
LOOP
IF prevmstcol IS NULL
THEN
INSERT INTO tab_mst_group
VALUES (r1.mstcol, prevgroupid);
prevmstcol := r1.mstcol;
ELSE
INSERT INTO tab_tmp_group
SELECT DISTINCT groupid
FROM tab_mst_group a, tab_dtl b, tab_dtl c
WHERE a.mstcol = b.mstcol
AND c.dtlcol = b.dtlcol
AND c.mstcol = r1.mstcol;
IF SQL%ROWCOUNT = 0
THEN
prevgroupid := prevgroupid + 1;
INSERT INTO tab_mst_group
VALUES (r1.mstcol, prevgroupid);
ELSE
SELECT MIN (groupid) INTO vtmpgroupid FROM tab_tmp_group;
UPDATE tab_mst_group
SET groupid = vtmpgroupid
WHERE groupid IN (SELECT groupid FROM tab_tmp_group);
INSERT INTO tab_mst_group
VALUES (r1.mstcol, vtmpgroupid);
SELECT MAX (groupid) INTO prevgroupid FROM tab_mst_group;
DELETE tab_tmp_group;
END IF;
END IF;
END LOOP;
END;
{code}
Question:
a. Can we achieve this in SQL instead of PL/SQL?
b. Overhead of read from TAB_DTL grows exponentially if the No of records in TAB_MST grows. How can we reduce the no of read from TAB_DTL as the actual no of rows in TAB_DTL are very high.
Thanks,
sukhijankHi, Sukhijank,
Thanks for the additional information. You didn't just learn those details since posting your first message, did you? If you post information like that in your first message, then people can use it to give you a better answer in the first reply.
The idea I had for a recursive WITH clause solution won't work after all.
I think the best solution will be in PL/SQL, using a table like tab_mst_group which you posted, but with an additional column:
CREATE TABLE TAB_MST_GROUP
mstcol NUMBER PRIMARY KEY,
groupid NUMBER,
levelnum NUMBER
CREATE INDEX tab_mst_group_groupid_levelnum
ON tab_mst_group (levelnum, groupid);
If llevelnum = 0, that means the assignment of the groupid is not certain; if levelnum > 0, then groupid is correct.
Here's a procedure you can use to populate the table:
CREATE OR REPLACE PROCEDURE tab_mst_group_populate
AS
new_groupid tab_mst_group.groupid%TYPE
:= 0;
new_levelnum tab_mst_group.levelnum%TYPE;
num_added PLS_INTEGER;
truncate_stmt VARCHAR2 (50) := 'TRUNCATE TABLE tab_mst_group';
BEGIN
-- ***** Remove old entries from the table *****
-- dbms_output.put_line (truncate_stmt || ' = truncate_stmt in tab_mst_group_populate'); -- Debugging
EXECUTE IMMEDIATE truncate_stmt;
-- ***** Populate table with all mstcols, and 1-member groups *****
INSERT INTO tab_mst_group (mstcol, groupid, levelnum)
SELECT m.mstcol
, m.mstcol AS groupid
, MIN ( CASE
WHEN o.mstcol IS NULL
THEN 1
ELSE 0
END
) AS lvlnum
FROM tab_mst m
LEFT JOIN tab_dtl d ON d.mstcol = m.mstcol
LEFT JOIN tab_dtl o ON o.dtlcol = d.dtlcol
AND o.mstcol != d.mstcol
GROUP BY m.mstcol;
-- ***** Get groupid for lowest mstcol that still needs one *****
WHILE new_groupid IS NOT NULL
LOOP
SELECT MIN (groupid)
INTO new_groupid
FROM tab_mst_group
WHERE levelnum = 0;
IF new_groupid IS NOT NULL
THEN
-- *** Confirm groupid for this one mstcol ***
UPDATE tab_mst_group
SET levelnum = 1
WHERE levelnum = 0
AND groupid = new_groupid;
new_levelnum := 2;
num_added := 1;
-- *** Add neighboring mstcols to this group ***
WHILE num_added > 0
LOOP
UPDATE tab_mst_group
SET groupid = new_groupid
, levelnum = new_levelnum
WHERE levelnum = 0
AND groupid IN (
SELECT d2.mstcol
FROM tab_mst_group g1
JOIN tab_dtl d1 ON d1.mstcol = g1.mstcol
JOIN tab_dtl d2 ON d2.dtlcol = d1.dtlcol
AND d2.mstcol != d1.mstcol
JOIN tab_mst_group g2 ON g2.mstcol = d2.mstcol
WHERE g1.levelnum = new_levelnum - 1
AND g1.groupid = new_groupid
AND g2.levelnum = 0
num_added := SQL%ROWCOUNT;
dbms_output.put_line (num_added || ' = num_added');
new_levelnum := new_levelnum + 1;
END LOOP;
END IF;
END LOOP;
END tab_mst_group_populate;
SHOW ERRORS
The basic strategy is that we start off assuming that every mstcol will be its own groupid. The CASE expression in the INSERT statement sets levelnum = 1 for mstcols that do not exist in the tab_dtl table, or are not related to other mstcols in tab_dtl. The loop after that looks for rows in tab_mst_group that are still 0, meaning that the assignment of grpupid still has to be confirmed or changed. It starts by finding the lowest mstcol that still has levelnum = 0, and makes that a new group. The inner loop looks for related mstcols and marks them as being in the same group.
You might combine tab_mst and tab_mst_group; I don't see any need to have a separate table (but maybe you do). If you do combine them, then you wouldn't truncate the table in the procedure. -
Trying to find ALL objects that point to one column...
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Solaris: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
I have multiple schemas, all which have tons of objects that point to one column of one table.
I tried to look at v$sqltext, and v$sqlarea, but it doesn't seem to show as expected.
Is there a view that I can look at that will show me all the objects that relate to one column?
my situation. Had to change the data structure of this one column. Changed the default value from a Y to an L. I have packages, functions, triggers...etc... that deal with this one column. I need to ensure that I go through EACH one and edit them to reflect the change to the table column. And again, this spans multiple schemas that point back to it.
I can't overlook any objects. Is there any one place to find this?
Thanks.Use view - DBA_DEPENDENCIES
select * from dba_dependencies
where type= 'TABLE'
and name = '<TABLE_NAME>';Another crude way...
select * from all_source
where lower(text) like lower('%<TABLE_COLUMN_NAME>%')
group by owner,name,type;But, this 'll not search in Views & MView queries.
HTH
Ranit B.
Edited by: ranit B on Oct 15, 2012 11:09 PM
-- added -
Display rows which has only unique column values
One of my table has the following data in it.
ORDER_NO IND_CODE
1002 DNA
1004 GEN
1005
1007 DNA
1008 DNA
1009 GEN
1010
1000 NULL
1001 NULL
1003 NULL
1006 NULL
1000 ZZZ
1005 ZZZ
I just want to display the rows with unique ORDER_NO.
SarvanYou have 1000 as duplicate values in the column. But both have different indcode.
Select distinct order_no from [table name]
If you need combination of order_no and ind_code as unique then .
Select distinct order_no, ind_code from [table name] -
Query to Find all the Tables and their corresponding columns,dataType in DB
Hi all,
I need a query which can give me all the Tables existing in my DB and their corresponding Columns existed for those tables and Datatype for each column .
Thanks in Advance,
viajyHi,
For your user tables you can use USER_TAB_COLUMNS.
Just give DESC USER_TAB_COLUMNS at your SQL> prompt.
You will know on that object.
Regards,
Sailaja -
How to select record in mulitple rows based on another field's values?
Hi,
sorry about the bad title, really not sure how to explain this
Have the following data:
Cost_center Activity_type
1005009401 CLBR0
1005009401 CLBR1
1005009401 TLBR0
1005009401 TLBR1
1005009401 VEH00
1005009402 CLBR3
1005009402 CLBR4
1005009402 TLBR5
1005009402 TLBR6
1005009402 VEH07
1005009901 CE000
1005009901 CLBR0
1005009901 CLBR1
1005009901 TLBR0
1005009901 TLBR1
1005009901 VEH01 I need to return a list of cost centers (with its associated activity types) that do not have activity types of CLBR0 and CLBR1 and TLBR0 and TLBR1 and VEH01. So in the above data, cost center 1005009401 and 1005009402 would be returned.
Any thoughts?
Thanks.
Edited by: dgouin on Aug 29, 2012 11:42 AM - added more sample data.
Edited by: dgouin on Aug 29, 2012 11:45 AM
Edited by: dgouin on Aug 29, 2012 11:49 AMSorta kludgey, but functional:
WITH ccs AS
SELECT '1005009401' AS CC, 'CLBR0' AS activity_type FROM dual
UNION ALL
SELECT '1005009401' AS CC, 'CLBR1' AS activity_type FROM dual
UNION ALL
SELECT '1005009401' AS CC, 'TLBR0' AS activity_type FROM dual
UNION ALL
SELECT '1005009401' AS CC, 'TLBR1' AS activity_type FROM dual
UNION ALL
SELECT '1005009401' AS CC, 'VEH00' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'CE000' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'CLBR0' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'CLBR1' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'TLBR0' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'TLBR1' AS activity_type FROM dual
UNION ALL
SELECT '1005009901' AS CC, 'VEH01' AS activity_type FROM dual
SELECT cc, activity_type
FROM ccs c1
WHERE 5 != (SELECT COUNT(DISTINCT activity_type)
FROM ccs c2
WHERE activity_type IN ('CLBR0','CLBR1','TLBR0','TLBR1','VEH01')
AND c1.cc = c2.cc
CC ACTIVITY_TYPE
1005009401 CLBR0
1005009401 CLBR1
1005009401 TLBR0
1005009401 TLBR1
1005009401 VEH00
Maybe you are looking for
-
I know this sounds crazy, but since upgrading to Leopard, I have on a number of occasions discovered items in the trash that I did not place there! Just now I opened an Excel file and closed it without making any changes. When I went to empty the tra
-
IPod Nano 7th Generation not charging
Has anyone had trouble with their iPod Nano 7th Generation not charging?
-
In my ipad2 Is there any way to recover a deleted note In Note app?
Is there a way to recover a deleted note in the Note App?
-
Nikon D800 & Sony A7r processing
I have aperture 3.5 and am using a 15" macbook pro from early 2011: 2.2 GHZ Intel core7, 8GB 1333DDR3 Ram, Intel HD Graphics 3000 512MB Graphics and the internal hard drive. I'm about the purchase either the 24MB Sony A7 or the 36MB A7r. I'm concerne
-
Having just installed Window8, I can no longer see some videos. Was told to download Flash. Tried to but nothing happend! Any ideas?? Guess I must need to change some settings.