Using distinct in where clause
Greedings,
I am trying to execute some kind of distinct using rowid in where clause but for some reason im not getting the appropriate result. Any guidance is welcome
SELECT acnt_code,cat,cat_desc,buc FROM so_budgets_cat where
Trim(buc)='S03'
and
NOT exists (SELECT 1
from so_budgets_cat tab2
where ( tab2.cat = so_budgets_cat.cat )
and tab2.ROWID > so_budgets_cat.ROWID
ORDER BY cat,so_budgets_cat.rowidThanks in advance
Additionally to the fact that we don't have an idea on the expected output, I can't understand the comparison of ROWIDs in your query. These are the logical addresses where the data reside in the disks, comparing them doesn't make sense to me; Oracle DB defines where to store, based on space availability in the disk allocation to the database occupation - and NOT in a logical sequence.
Maybe the existing row is stored in an address that is not a higher number than other, and so it is not being retrieved in your sub-query - hence your test for distinction is failing.
Similar Messages
-
Error while using REMAP_TABLE and WHERE clause together in IMPDP
I am trying to move some records from a very large table to another small table.
I am facing trouble while using REMAP_TABLE and WHERE clause together in IMPDP.
Problem is data filter is not getting applied and all records are getting imported.
here is how I have simulated this. please advice.
CREATE TABLE TSHARRHB.TMP1
A NUMBER,
B NUMBER
begin
Insert into TSHARRHB.TMP1
(A, B)
Values
(1, 1);
Insert into TSHARRHB.TMP1
(A, B)
Values
(2, 2);
COMMIT;
end;
expdp system/password TABLES=tsharrhb.TMP1 DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp REUSE_DUMPFILES=YES LOGFILE=EXP.log PARALLEL=8
impdp system/password DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY='TSHARRHB.TMP1:"WHERE TMP1.A = 2"' REMAP_TABLE=TSHARRHB.TMP1:TMP3 CONTENT=DATA_ONLY
Import: Release 11.2.0.1.0 - Production on Fri Dec 13 05:13:30 2013
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/********@GRD6.RBSG DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp LOGFILE=SSD_93_TABLES_FULL_EXP.log PARALLEL=8 QUERY=TSHARRHB.TMP1:"WHERE TMP1.A = 2" REMAP_TABLE=TSHARRHB.TMP1:TMP3 CONTENT=DATA_ONLY
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "TSHARRHB"."TMP3" 5.421 KB 2 rows
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at 05:13:33
here I am expecting only 1 record to get imported but both the records are getting imported. please advice.The strange thing compared to your output is that I get an error when I have table prefix in the query block:
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/******** DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY=SYSADM.TMP1:"WHERE TMP1.A = 2" REMAP_TABLE=SYSADM.TMP1:TMP3 CONTENT=DATA_ONLY
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
ORA-31693: Table data object "SYSADM"."TMP3" failed to load/unload and is being skipped due to error:
ORA-38500: Unsupported operation: Oracle XML DB not present
Job "SYSTEM"."SYS_IMPORT_FULL_01" completed with 1 error(s) at Fri Dec 13 10:39:11 2013 elapsed 0 00:00:03
And if I remove it, it works:
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_FULL_01": system/******** DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY=SYSADM.TMP1:"WHERE A = 2" REMAP_TABLE=SYSADM.TMP1:TMP3 CONTENT=DATA_ONLY
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "SYSADM"."TMP3" 5.406 KB 1 out of 2 rows
Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at Fri Dec 13 10:36:50 2013 elapsed 0 00:00:01
Nicolas.
PS: as you can see, I'm on 11.2.0.4, I do not have 11.2.0.1 that you seem to use. -
Using function in where clause
I have created a function as follows
create or replace FUNCTION get_codes RETURN varchar2 IS
scodes varchar2(50) := 'A1,A2';
BEGIN
scodes := '('''||REPLACE(scodes,',',''',''')||''')';
return scodes;
END;
this function returns ('A1','A2')
now i want to use this in where clause, both below statements fetches no rows
select * from tablea where code in (select get_codes from dual);
select * from tablea where code in get_codes;
but the following will fetch rows
select * from tablea where code in ('A1','A2')
how to use function in where clause
ThanksHi,
The code that works:
where code in ('A1','A2')is testing whther code is either of two 2-character strings, A1 or A2.
The ones that don't work, such as:
where code in get_codes;are comparing code to one 9-character string: 'A1','A2', where characters 1, 4, 6 and 9 are single-quotes. (The function can only return one value.)
You can use dynamic SQL to embed that 9-character string in part of your query, where it will be interpreted as two 2-character strrings.
[Oracle Base|http://www.oracle-base.com/articles/misc/DynamicInLists.php] and AskTom have good pages on the subject of dynamic IN-lists.
Of you can use INSTR or LIKE:
where INSTR ( get_codes
, '''' || code || ''''
) > 0 -
Hello all,
I am new to Oracle, currently using 10G + aspvbscript.
I've been trying to query data using date in where clause but nothing seems to work.
The column is in date format.
It gets printed out like this: 5/1/2010 11:21:19 AM
I tried using this query:
SELECT * from table where TRUNC(user_date) > to_date('FEB-01-2010:00:00:00','mm-dd-yyyy:HH24:MI:SS') order by user_date asc.
It does return an output but it returns everything in table and does not take WHERE clause into consideration however, it does sort the date in ascending order.
I've tried getting rid of TRUNC tried to format date in a different way but no such luck.
Please point me to the right direction.
Thanks.Welcome to the forums!
In cases like this it is helpful if you can provide the following information:
1. Oracle version (SELECT * FROM V$VERSION)
2. Sample data in the form of CREATE / INSERT statements.
3. Expected output
4. Explanation of expected output (A.K.A. "business logic")
5. Use \ tags for #2 and #3. See FAQ (Link on top right side) for details.
I'll try and take a stab at your request based on the data given. What your query says is that it will return all rows that have a date greater then 2/1/2010 (MM/DD/YYYY). If your query is returning all rows then maybe the possibility exists that all the dates in the table are greater then 2/1/2010. Have you checked all dates to see if this is the case?
Also, one note about your TO_DATE() function.to_date('FEB-01-2010:00:00:00','mm-dd-yyyy:HH24:MI:SS')The date format does not match the string you are using with respect to month. Your string has 'FEB' but the format is 'MM' which is the numeric representation of the month. Although Oracle was able to convert it to the proper date on my system you should try and maintain consistency between the string and the date format used. -
Can i use Decode in Where clause
Hi,
Can i use Decode in Where clause Please Do the need full on the same.
Thanks,
Sanjeev.set serveroutput on
DECLARE
posn PLS_INTEGER := 0;
empid PLS_INTEGER := 178;
x NUMBER;
BEGIN
SELECT NVL(SUM(ah.quantity * ah.saleprice * ap.payoutpct), 0)
INTO x
FROM accessoryhistory ah, payoutpercentage ap,
sku s, store st
WHERE empid = DECODE(posn,
0, st.areadir,
1, st.areamgr,
2, NVL(st.storemgr1, st.storemgr2),
3, NVL(st.asstmgr1, NVL(st.asstmgr2,
st.asstmgr3)))
AND ah.statustype IN ('ACT', 'DEA')
AND ah.store = st.store
AND s.dbid = ah.dbid
AND s.sku = ah.sku
AND ap.productgroup = s.productgroup
AND ap.position = posn;
dbms_output.put_line(x);
END;
/http://psoug.org/reference/decode_case.html -
Can both in-row and off-row LOBs be used in a where clause?
We are preparing to upgrade ASE from version 15.5 to 16.0. One of the features that is very appealing has to do with the changes made concerning the handling of LOBs. In particular, the ability to use a LOB column in search arguments (where clause) is something our developers have longed for since the retirement of the full-text search option. So, in version 16.0, can any column with a datatype of text be used as a search argument? Are there any restrictions.
Thanks in advance.Hi Kevin,
The in-row LOB feature is mainly designed to save space when a text column has many short values, which is a particularly bad problem when the server uses a large page size (like 16K) as ASE would use a full 16K to store even a single bye "Y". I don't think the feature made any change in how text can be used in search arguments. i.e. you can still use LIKE and IS [NOT] NULL, but not others.
Example:
1> create table t (x text in row (8))
2> go
1> insert t values ("abc")
2> insert t values ("abcdefghijkl")
3> go
(2 rows affected)
1> select * from t where x like "%c%"
2> go
x
abc
abcdefghijkl
(2 rows affected)
1> select * from t where x !> "c"
2> go
Msg 257, Level 16, State 1:
Server 'redhead', Line 1:
Implicit conversion from datatype 'TEXT' to 'VARCHAR' is not allowed. Use the
CONVERT function to run this query.
Msg 306, Level 16, State 5:
Server 'redhead', Line 1:
TEXT, IMAGE and UNITEXT datatypes may not be used in a WHERE clause, except with
the LIKE expression and IS [NOT] NULL predicate on columns. -
Using a dummy where-clause to force the use of an index
I notice that an index only gets used when I use the index key in the where clause. Should I use a dummy where clause to force the index to be used?
SQL> create table emp (
2 empno NUMBER(5),
3 empname VARCHAR2(15) );
Table created.
SQL> create index idx_emp_no on emp (empno);
Index created.
SQL> insert into emp (empno, empname) values (1, 'Peter');
1 row created.
SQL> set autotrace traceonly;
SQL> select empno from emp;
Execution Plan
Plan hash value: 3956160932
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 1 | 13 | 3 (0)| 00:00:01 |
SQL> select empno from emp where empno > 0;
Execution Plan
Plan hash value: 434430053
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 13 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_EMP_NO | 1 | 13 | 1 (0)| 00:00:01 |
As you can see, using a dummy where clause (empno > 0), I manage to reduce the cost from 3 to 1.Again. Be careful with comparisons. But I like the discussion. It is usefull to carefully look at what happens "behind the scenes" and find a sensible explaination for that.
Your new scenario now is different. By selecting one specific row instead of selection all you already made an assumption. That only one or few of the rows are returned. Andre's statement still is correct. Now the CBO will prefere the index scan.
The CBO now has to decide between two options.
Option a) use the index.
This means =>
Step 1: Access the index to find the value
Step 2: Access the table using the rowid that was found in the index leaf entry.
Option b) scan the full table
This means =>
Step 1: Iterate over all rows of the table
Step 2: Apply a filter condition (empno = :x)
We can see this execution plan by adding a hint to the query.
select /*+ FULL(emp) */ * from emp where empno = 1;This hint will force the CBO to access the table emp using a full table scan.
The cost in my environment for option B is 3.
Option A has a cost with 2. Therefore the CBO prefers Option A.
However this can easily change.
Consider the following
begin
for i in 1..1000 loop
insert into emp (empno, empname) values (1, 'Employee');
end loop;
end;
commit;
execute dbms_stats.gather_table_stats(user,'EMP');The run the select again.
SQL> set autotrace traceonly
SQL> select * from emp where empno = 1;
1001 Zeilen ausgewõhlt.
Ausf³hrungsplan
Plan hash value: 3956160932
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1001 | 12012 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| EMP | 1001 | 12012 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter("EMPNO"=1)
Statistiken
1 recursive calls
0 db block gets
74 consistent gets
0 physical reads
0 redo size
18356 bytes sent via SQL*Net to client
1250 bytes received via SQL*Net from client
68 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1001 rows processedThe CBO now prefers the full table scan and not the index access.
If we force it to use an index then the cost increases.
SQL> set linesize 100
SQL> select /*+INDEX(emp) */ * from emp where empno = 1
1001 Zeilen ausgewõhlt.
Ausf³hrungsplan
Plan hash value: 2426388914
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1001 | 12012 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1001 | 12012 | 5 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_EMPNO | 1001 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("EMPNO"=1)
Statistiken
0 recursive calls
0 db block gets
139 consistent gets
0 physical reads
0 redo size
30550 bytes sent via SQL*Net to client
1250 bytes received via SQL*Net from client
67 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1001 rows processed
SQL>The cost using the index range scan is now 5. WHile the FTS is still 3. Therefore the CBO prefers to use the FTS. -
Using decode in where clause with user defined function
Hi,
I have a below query which is failing as the function in the decode taking all cust_account_id as input parameter instead of the one which satisfies the condition in the inner query.So please provide a solution how can i pass only the selected one.
SELECT hca.cust_account_id
FROM hz_cust_accounts hca
WHERE hca.org_id=FND_PROFILE.value('ORG_ID')
AND hca.cust_account_id = (SELECT DISTINCT hcasa.cust_account_id
FROM hz_cust_acct_sites_all hcasa
WHERE hcasa.cust_account_id =hca.cust_account_id
AND hca.org_id = hcasa.org_id)
AND DECODE (hca.status , 'A', xx_ar_cust_audit_pkg.get_ship_to_order_type(hca.cust_account_id)) IS NOT NULL
Thanks,
AbhilashI'm having to guess without access to your tables, but I think changing the IN to a join should produce the same results. The JOIN should be evaluated before applying the WHERE clause, so this may resolve your problem.
SELECT hca.cust_account_id
FROM hz_cust_accounts hca
INNER JOIN hz_cust_acct_sites_all hcasa
ON hcasa.cust_account_id = hca.cust_account_id
AND hca.org_id = hcasa.org_id
WHERE hca.org_id = FND_PROFILE.value('ORG_ID')
AND DECODE (hca.status , 'A', xx_ar_cust_audit_pkg.get_ship_to_order_type(hca.cust_account_id)) IS NOT NULLAlternately, you could next part of the query and break the DECODE into the parent so it is evaluated after the inner query. This is likely uglier from a performance standpoint, though:
SELECT cust_account_id
FROM
SELECT hca.cust_account_id, hca.status
FROM hz_cust_accounts hca
WHERE hca.org_id=FND_PROFILE.value('ORG_ID')
AND hca.cust_account_id = (SELECT DISTINCT hcasa.cust_account_id
FROM hz_cust_acct_sites_all hcasa
WHERE hcasa.cust_account_id =hca.cust_account_id
AND hca.org_id = hcasa.org_id)
WHERE DECODE (status , 'A', xx_ar_cust_audit_pkg.get_ship_to_order_type(cust_account_id)) IS NOT NULL; -
Clarification on using function in where clause of oracle sql query
I have an issue in regarding function using where clause of sql query..
We are facing performance issue while executing query, so in what ways to improve the performance of the query which i have posted below.
select col ,case when my_function(parameter)
from tab1 a ,tab2 b,tabl3 c
where a.column1=b.column2
and b.column3 =c.column6
and my_function(parameter)>0
Regards
Dinesh
Edited by: wild fire on May 18, 2012 4:15 PMDinesh,
remind that when you use a function in the where clause it normally will get started for each record in the table.
So your answer is two-fold:
1. make the function only start when needed by adding a function based index on the table (this will make inserts and updates slower)
2. make the function faster by adding the DETERMINISTIC clause if possible. this will make Oracle "cache" the result of the function.
Regards,
Richard
blog: http://blog.warp11.nl
twitter: @rhjmartens
If this question is answered, please mark the thread as closed and assign points where earned.. -
Hi all
We can use decode function in the Select columns as well as Group by Columns as well as Having Clause
Can we use decode function in the where clause also. If yes can u give small sample
Suresh Bansal""DECODE in the WHERE clause"
http://psoug.org/reference/decode_case.html
WHERE empid = DECODE(posn,
0, st.areadir,
1, st.areamgr,
2, NVL(st.storemgr1, st.storemgr2),
3, NVL(st.asstmgr1, NVL(st.asstmgr2,
st.asstmgr3))) -
Why I cannot use RowID in where clause but can use it in order by clause
I am on SQL Server 2008.
1. If I use
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
order by RowID
Statement works
But
2. If I use
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
where RowID > 10000
I get error, RowID is an invalid column Name why? How to correct query 2.This is due to the logical evaluation order of a SELECT statement. Logically, a SELECT statement is computed in the order:
FROM (which includes JOIN)
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
OFFSET
Thus, you can use what is defined in the SELECT list in the ORDER BY clause, but not in the WHERE clause.
In the case of row_number(), this has immediate repurcussions. row_number() is computed from the rows as they arrive the SELECT clause, and if you then you would filter on the value in the WHERE clause you would be going round in circles.
To do what you are looking for, you use a nested table, for instance with a CTE:
WITH numbering AS (
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
SELECT *
FROM numbering
WHERE RowID > 10000
Erland Sommarskog, SQL Server MVP, [email protected] -
Can we use Case in Where Clause along with Exists
Hi Everybody,
Can we use Case in the where clause with exists? As i have a requirement in which i have to check whether value exists in 6 views, now depending on some value(gns_type )of select clause i have to attach a paticular exists else the performance dies.
Please go through the query any suggestion appreciated.
Thanks
SELECT count(*)
FROM
(SELECT eah.changed_date,
decode(eua.is_deleted, 'N', decode(eah.alert_type, NULL, 'GN', 'R', 'GAR', 'G', 'GAG', 'Y', 'GAY'), 'Y', decode(eah.alert_type, 'R', 'GDR', 'G', 'GDG', 'Y', 'GDY', NULL, 'GN'), NULL, 'GN') AS
alert_type,
decode(eac.pta_line, 'N', '') ptaline,
eac.exp_type_desc,
eac.supplier_name,
eac.transaction_id,
eah.gns_type,
eac.po_amount,
eac.po_end_date,
eah.notes,
eua.is_deleted,
eac.expenditure_type,
eua.gns_alert_summary_id,
eah.changed_date alert_date,
eua.user_alert_id,
eah.reference_number,
decode(eac.cms_pta_line,'N','',eac.cms_pta_line) cms_pta_line,
cms_po_amount,
cms_po_end_date,
mgns.is_decommitted,
eac.gns_alert_id,
eah.gns_type source_name
FROM xxdl.xxdl_sc_gns_alerts_summary eah,
xxdl.xxdl_sc_gns_detail_alerts eac,
xxdl.xxdl_sc_gns_user_alerts eua,
xxdl.xxdl_sc_manage_gns_master mgns
WHERE eah.gns_alert_summary_id = eac.gns_alert_summary_id
AND eah.gns_alert_summary_id = eua.gns_alert_summary_id
AND eah.transaction_id = eac.transaction_id
AND eah.transaction_id = mgns.transaction_id)
a
WHERE(EXISTS
(SELECT 1
FROM xxdl_sc_mng_gns_pta_req_hc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
OR
EXISTS( SELECT 1
FROM xxdl_sc_mng_gns_pta_inv_hc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
OR
EXISTS(SELECT 1
FROM xxdl_sc_mng_gns_pta_req_sc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
OR
EXISTS(SELECT 1
FROM xxdl_sc_mng_gns_pta_inv_sc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
OR
EXISTS( SELECT 1
FROM xxdl_sc_mng_gns_pta_po_sc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
OR
EXISTS (SELECT 1
FROM xxdl_sc_mng_gns_pta_po_hc_v x
WHERE x.transaction_id = a.transaction_id
AND x.source_name = a.source_name
AND x.project_id = 69309
AND x.task_id = 242528
AND x.award_id = 34694)
AND TRUNC(alert_date) >= TRUNC(add_months(sysdate, -1))
AND TRUNC(alert_date) <= TRUNC(sysdate)
AND is_deleted = 'N'
ORDER BY changed_date DESCyou can do
WHERE
CASE WHEN (something) THEN
CASE WHEN EXISTS (SELECT * from ...) THEN 1 ELSE 0 END
WHEN (something else) THEN
CASE WHEN EXISTS (SELECT * from ...) THEN 1 ELSE 0 END
END = 1Looking at your current query, it looks like all those exist statements could be a lot neater, maybe like:
WHERE (69309,242528,34694) IN
(SELECT project_id,task_id,award_id FROM
(Select project_id,task_id,award_id,transaction_id,source_name
FROM
xxdl_sc_mng_gns_pta_req_hc_v
UNION ALL
Select project_id,task_id,award_id
xxdl_sc_mng_gns_pta_inv_hc_v
...) x
where a.transaction_id = x.transaction_id
and a.source_name = x.source_name
)or put the tuple in the where clause at the bottom -
Using collections in WHERE clause
Hi friends,
Please help me to use an associate array in SQL query (WHERE clause). The requirement is similar to the following example:
===============================================
declare
type rec_emp is record(emp_id integer, emp_name varchar2(100));
type ty_emp is table of rec_emp index by pls_integer;
tb_emp ty_emp;
type ty_emp_history is table of emp_history%rowtype index by pls_integer;
tb_emp_history ty_emp_history;
begin
select emp_id, emp_name
bulk collect into tb_emp
from emp
where dept_id = 10;
--Now I want to fetch records from emp_history based on the values in tb_emp. So I want a query something like the following.
--(I know that join can be used to achive this. But it is just an example. I need to achive this in collections.)
select *
bulk collect into tb_emp_history
from emp_history
where emp_id = tb_emp.emp_id
and emp_name = tb_emp.emp_name;
end;
===============================================
Thanks in advance.
Edited by: Iniyavan on Oct 26, 2012 11:50 AM>
Please help me to use an associate array in SQL query (WHERE clause).
select *
bulk collect into some_array
>
there is no variable 'some_array' in what you posted.
If you want help with your code you have to post the code you are really using, not some hacked-up version of it that has errors.
Here is sample code that shows how to treat a collection as a table using the TABLE operator
-- type to match emp record
create or replace type emp_scalar_type as object
(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)
-- table of emp records
create or replace type emp_table_type as table of emp_scalar_type
declare
tb emp_table_type;
deptnoList sys.OdciNumberList;
BEGIN
select emp_scalar_type(empno, ename, job, mgr, hiredate, sal, comm, deptno)
bulk collect into tb from emp;
SELECT deptno bulk collect
INTO deptnoList
FROM dept where deptno not in (select deptno from table(tb));
for i in 1..deptnoList.count loop
dbms_output.put_Line(deptnoList(i));
end loop;
END;Note that tb is a collection and is useds in the subquery 'select deptno from table(tb)'. -
I am using the following query for as part of my effort
select b.account_number,
b.restriction_code,
a.cusip_number,
a.symbol,
c.shares,
round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) outstanding_share_percent
from br_securities a,
br_accounts b,
(select account_number,cusip_number,sum(shares) shares
from br_positions
where account_number not in (select account_number
from br_house_accounts)
group by account_number,cusip_number) c
where a.cusip_number = c.cusip_number
and b.account_number = c.account_number
and b.open_flag = 'Y'
and a.security_type||a.security_sub_type in ('A01','B01','B02','C02')
and (round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) > 10
or round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) < 0
or round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) is null)
order by outstanding_share_percent desc;
Since the expression round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) re-occurs in
the where clause, I tried using the query as shown
select b.account_number,
b.restriction_code,
a.cusip_number,
a.symbol,
c.shares,
a.shares_outstanding,
round(((c.shares/nullif(to_number(a.shares_outstanding),0))*100),4) outstanding_share_percent
from br_securities a,
br_accounts b,
(select account_number,cusip_number,sum(shares) shares
from br_positions
where account_number not in (select account_number
from br_house_accounts)
group by account_number,cusip_number) c
where a.cusip_number = c.cusip_number
and b.account_number = c.account_number
and b.open_flag = 'Y'
and a.security_type||a.security_sub_type in ('A01','B01','B02','C02')
and ( outstanding_share_percent > 10
or outstanding_share_percent < 0
or outstanding_share_percent is null)
order by outstanding_share_percent desc;
SQL*Plus returned this error
ERROR at line 21:
ORA-00904: "OUTSTANDING_SHARE_PERCENT": invalid identifier
Is there a way to modify the query for a better readability?You have to have the query in a sub-query. Like this.
SELECT *
FROM (SELECT b.account_number,
b.restriction_code,
a.cusip_number,
a.symbol,
c.shares,
a.shares_outstanding,
round(((c.shares / nullif(to_number(a.shares_outstanding), 0)) * 100), 4) outstanding_share_percent
FROM br_securities a,
br_accounts b,
(SELECT account_number,
cusip_number,
SUM(shares) shares
FROM br_positions
WHERE account_number NOT IN (SELECT account_number FROM br_house_accounts)
GROUP BY account_number,
cusip_number) c
WHERE a.cusip_number = c.cusip_number
AND b.account_number = c.account_number
AND b.open_flag = 'Y'
AND a.security_type || a.security_sub_type IN ('A01', 'B01', 'B02', 'C02'))
WHERE (outstanding_share_percent > 10 OR outstanding_share_percent < 0 OR outstanding_share_percent IS NULL)
ORDER BY outstanding_share_percent DESC; -
Using CASE on WHERE clause?
Is it posible to use a CASE on the WHERE clause?
I always used the following syntax on MSSQL
but Oracle aparently doesn't accept it:
SELECT...
WHERE
CASE WHEN keyword IS NOT NULL THEN
CONTAINS(field, keyword) > 0
END AND
CASE WHEN varcode IS NOT NULL THEN
code = varcode
END AND
OTHER STATEMENTSSQL> SELECT
2 COUNT(*) OVER() total,
3 ed_fotos.id AS COD_FOTO,
4 ed_fotos.foto.getwidth()/100 AS VLR_LARGURA,
5 ed_fotos.foto.getheight()/100 AS VLR_ALTURA,
6 ed_fotos.arquivo AS NOM_ARQUIVO,
7 ed_areas.nome AS NOM_REDACAO
8 FROM edt.ed_fotos ed_fotos
9 INNER JOIN edt.ed_areas ed_areas ON
10 ed_areas.id = ed_fotos.redacao_id AND
11 (ed_areas.ind_licenciada <> 'S' OR
12 ed_areas.ind_licenciada IS NULL
13 OR (ed_areas.id IN (SELECT * FROM THE (SELECT CAST(fda_
adm.in_list('') AS fda_adm.mytableType) FROM dual)))
14 )
15 LEFT JOIN edt.ed_creditos_fotos ed_creditos_fotos ON
16 ed_creditos_fotos.foto_id = ed_fotos.id
17 LEFT JOIN edt.ed_itens ed_itens ON
18 ed_itens.foto_id = ed_fotos.id
19 LEFT JOIN edt.ed_edicoes ed_edicoes ON
20 ed_edicoes.id = ed_itens.edicao_id
21 LEFT JOIN edt.vw_dedoc_ccda vw_dedoc_ccda ON
22 vw_dedoc_ccda.num_ccda = ed_fotos.num_ccda_sct AND
23 vw_dedoc_ccda.cod_tipo_documento IN ('B','C','C1','C2')
24 LEFT JOIN fda_adm.vw_lui vw_lui ON
25 vw_lui.foto_id = ed_fotos.id AND
26 vw_lui.cod_tipo_documento IN ('B','C')
27 WHERE
28 CASE WHEN 'BUSH' IS NOT NULL THEN
29 CONTAINS(ed_fotos.detalhe, '{BUSH} within termo
OR {BUSH} within headline OR {BUSH} within desc') > 0
30 END) AND
31 1 = 1
32 GROUP BY
33 ed_fotos.id,
34 ed_fotos.foto.getwidth(),
35 ed_fotos.foto.getheight(),
36 ed_fotos.registro,
37 ed_fotos.arquivo,
38 ed_areas.nome,
39 ed_areas.id
40 ORDER BY
41 ed_fotos.id DESC
42 /
CONTAINS(ed_fotos.detalhe, '{BUSH} within termo
OR {BUSH} within headline OR {BUSH} within desc') > 0
ERRO on line 29:
ORA-00905: missing keyword
Maybe you are looking for
-
Making changes to PHP web pages
Hi. I am wondering if I can just open a .php file in DW and just make text and image changes just as I would an html file. Or do I need to know and be able to mess with PHP code to do this. Thanks in advance. -Bonzojr
-
Sd card reader no longer reading - windows 7 pavilion g7-1273nr
My SD card reader is no longer recognizing my SD cards.
-
Why negative sign is appearing in right side of output
Hi ABAP Gurus , I have wrriten a BDC which display the output and also downloads the list into notepad. While displaying output on the screen that particular field shows minus sign on the right and in the downloaded file the sign is in the extreme ri
-
Is anyone having issues with installing the 32 bit version of Adobe Presenter?
I am trying to install the 32 bit version of Presenter on my computer from the downloaded file on the website. I have an authorization code I put in and then when it starts to download it asks to insert the disk when there is not one. Below are the s
-
How to restore to back up after setting up as new
I received my iPhone 4S in the mail today and in my excitement set it up as a new phone because I was away from my Macbook that I synced my 3GS to. What's the easiest way to restore to the 3GS's back up once I have access again? Or have I shot myself