I am trying to return a list of cell phone numbers from the S_CONTACT table of Siebel where the value contains anything other than numbers.
The query I am using is:
select cell_ph_num
from s_contact
where regexp_replace(cell_ph_num, '0|1|2|3|4|5|6|7|8|9', '') <> ''
But I get no results.
However, when I run the following query:
select regexp_replace(cell_ph_num, '0|1|2|3|4|5|6|7|8|9', '') from s_contact
I get a load of results.
Do these results not match the "does not equal empty string" clause?
'' is NULL in oracle.. so it has to be IS NOT NULL
select cell_ph_num
from s_contact
where regexp_replace(cell_ph_num, '0|1|2|3|4|5|6|7|8|9', '') IS NOT NULL
OR We can use REGEXP_LIKE this way by POSIX class
WHERE REGEXP_LIKE (cell_ph_num,'[^[:DIGIT:]]');
OR Perl style POSIX equivalent
WHERE REGEXP_LIKE (cell_ph_num,'\D');
Related
I have a lookup table that contains forbidden values/strings and a rule number which depicts where the value cannot occur. So for e.g., I have ‘C/O’ as a value and this can’t occur anywhere in a name field. I also have ‘P.O’ which can’t occur in an address. I am attempting to create a data quality report to flag these values without hard coding. I have tried:
Select
A.name
,A.address
From customer A
Where a.name LIKE (Select concat(‘%’, exclusion_value, ‘%’) from DQ_lookup where rule_number=2)
Or a.address LIKE (Select concat(‘%’, exclusion_value, ‘%’) from DQ_lookup where rule_number=1)
This fails. How if at all can I get this to work ?
For matching patterns in hive, you would need to use rlike.
A RLIKE B
: NULL if A or B is NULL, TRUE if any (possibly empty) substring of A matches the Java regular expression B, otherwise FALSE. For example, 'foobar' RLIKE 'foo' evaluates to TRUE and so does 'foobar' RLIKE '^f.*r$'.
Something as below would do.
Select
A.name,
A.address
From customer A
Where
a.name RLIKE (Select exclusion_value from DQ_lookup where rule_number=2)
OR a.address RLIKE (Select exclusion_value from DQ_lookup where rule_number=1)
Note: exclusion_value should be a regex expression.
I am just wondering if use = sign operator with sub-query instead of IN
Is it correct way ? and meet the oracle standard ?
Example
select column_name from my_table_1 where id = (select max(id) from my_table_2);
The Difference is related to the number of rows returned. If you have only one row returned from nested sql you may prefer both = or in operators. But if multiple rows returned from nested query, use in operator.
So, in your sql example you may prefer using any of the operators. Since, max functions returns only one row.
As you are fetching maximum value from subquery to compare with id, Both(= and IN )will work fine. But If you are trying to fetch more than one row then you have to use IN keyword.
If you have 1 result in sub query you are fine with using = sign, except when data type is wrong, for example , checking with same data type of dummy VARCHAR2(1)
select * from dual where 'X' = (select max(dual.dummy) from dual);
Is similar to using in (also same explain plain)
select * from dual where 'X' in (select max(dual.dummy) from dual);
But checking with different/wrong data type will result with exception ORA-01722 Invalid number
select * from dual where 1 =(select max(dual.dummy) from dual);
Let's say I have a jsonb column type called "data" for the table "recipes". I'm trying to find all records that have "data" filled out (i.e. "data" is not null or an empty bracket {}).
I know for hstore columns, using ruby, you can use a query like this to do so:
Recipe.where("data <> ''")
Is there an equivalent query for jsonb?
Updated after reading the question properly:
You can check for columns with NO data like this
SELECT * FROM table WHERE json_column IS NOT NULL
So this would then be
Recipe.where.not('data IS NULL')
And for columns with non-empty hashes like this:
SELECT * FROM table WHERE json_column <> '{}'
This translates to:
Recipe.where('data <> ?', '{}')
# or
Recipe.where("data <> '{}'")
A good way to verify your query is to run them in SQL first (so you avoid AR and its translation of Ruby to SQL). Then you can try and build the query in AR and use to_sql to see what AR makes of your queries.
Recipe.where('data <> ?', '{}').to_sql
#=> "SELECT \"recipies\".* FROM \"recipies\" WHERE (data <> '{}')"
vs.
Recipe.where('data <> ?', {}).to_sql
#=> "SELECT \"recipies\".* FROM \"recipies\" WHERE (data <> NULL)"
I have a requirement where i have to fetch some rows based on a condition and apart from that 2 more rows should be there in output one will be * and other will be a blank row. I am using the approach of Union to club that 2 extra rows.
Query :
SELECT '' as PROMO_GRP_CD , '' as PROMO_GRP_DESC, '' as PROMO_GRP_ALT_DESC
from PROMO_GROUP
UNION
SELECT '*' as PROMO_GRP_CD , 'All' as PROMO_GRP_DESC, 'Tous' as PROMO_GRP_ALT_DESC
from PROMO_GROUP
UNION
SELECT PROMO_GRP_CD,PROMO_GRP_DESC,PROMO_GRP_ALT_DESC from PROMO_GROUP
where ACC_TYPE = '*' and ACC_SUB_TYPE = '*' and SUBMARKET = '*'
In above Query first 2 selects from Table PROMO_GROUP gives me a blank row and a row with * value and below that i have normal select to retrieve data from Table PROMO_GROUP based on condition.
Is there any other optimum way through which i can achieve this ?
If you want to do it in query only, this is the best way. You should remove the from promo_group part from first two queries
But if you can, you should handle this in your code instead of your query
You need to create each dummy row using a SELECT clause that has no FROM clause (or in Oracle, from the special DUAL table, so it produces exactly one row), and UNION those two with the actual query. Like this:
SELECT '' as PROMO_GRP_CD , '' as PROMO_GRP_DESC, '' as PROMO_GRP_ALT_DESC FROM DUAL
UNION
SELECT '*' as PROMO_GRP_CD , 'All' as PROMO_GRP_DESC, 'Tous' as PROMO_GRP_ALT_DESC FROM DUAL
UNION
SELECT PROMO_GRP_CD,PROMO_GRP_DESC,PROMO_GRP_ALT_DESC from PROMO_GROUP
WHERE ACC_TYPE = '*' and ACC_SUB_TYPE = '*' and SUBMARKET = '*'
You can append the returned result with your two records (adding two element to the array). The result will be the same and you won't have the overhead of the UNION.
Of course you didn't specify what language you are using to run the query through. I am presuming your language will allow this.
hi guy i have a query that give me the followin error:
ORA-01791: not a SELECTed expression
this is the select expresison , please can you tell me why ?
declare
freqLettura varchar2(64);
billingcy varchar2(64);
begin
freqLettura := null;
billingcy := null;
for rec in ( select distinct(fn_get_facilityid(z.uidfacility) ) as a, 1 as b
from facilityhistory z,
locality l ,
plant p ,
ztmp_sam_tb_sdv zsdv ,
ztmp_sam_tb_plantcode zplant ,
sam_tb_ca_pdr sam,
meterhistory mh,
meter m ,
meterclass mc
where
Z.UIDLOCALITY = L.UIDLOCALITY and
p.UIDPLANT = L.UIDPLANT and
z.uidaccount = zsdv.uidaccount and
p.plantcode = zplant.plantcode and
sam.uidfacility = z.uidfacility and
z.stoptime is null and
sam.status = 'U' and
mh.uidfacility = z.uidfacility and
mh.uidmeter = m.uidmeter and
m.uidmeterclass = mc.uidmeterclass and
(billingcy is null or p.UIDBILLINGCYCLE = billingcy )
AND
(
(
(freqLettura = 'G') AND ( mh.corrmeterid is not null and mh.stoptime is null and mc.maxflowmeter >= SAM_FN_GET_PARAMETER_FLOAT('MAXFLOWMET_DETT_GIORN'))
)
OR
(
nvl(freqLettura,'nullo') <> 'G' AND (freqLettura is null or sam.readfrequency = freqLettura)
)
) and ROWNUM = 1 order by sam.stoptime, sam.uidsamtbpdr desc ) loop
begin
insert into ztmp_sam_tb_elab_pdr (facilityid, uidbatchrequest) VALUES (rec.a, rec.b);
exception
when dup_val_on_index then
null;
end;
end loop;
end;
Whenever you get an Oracle error message you don't understand, the first thing to do is look up the meaning. One way is simply to Google it. In this case the full description found in
Oracle9i Database Error Messages is:
ORA-01791 not a SELECTed expression
Cause: There is an incorrect ORDER
BY item. The query is a SELECT DISTINCT query with an ORDER BY clause.
In this context, all ORDER BY items must be constants, SELECT list
expressions, or expressions whose operands are constants or SELECT
list expressions.
Action: Remove the inappropriate ORDER BY item from the SELECT list
and retry the statement.
(Oddly this error message isn't documented in the 10G or 11G manuals, despite still being raised!)
This matches the statement you have written, which is a SELECT DISTINCT query where you are trying to order the results by a column that you did not select.
If you think about it, what you are asking for doesn't make sense: by selecting DISTINCT values that do not include sam.stoptime (for example) you may be consolidating many rows with different values for sam.stoptime, so which one would govern the ordering?
Also, as Noel's answer points out, there is no reason to have an ORDER BY clause in this code anyway, so the solution is simply to remove it.
If you are using DISTINCT in your SELECT query, then your ORDER BY clause should contain only those columns that your selecting. In this case sam.stoptime, sam.uidsamtbpdr are not there in SELECT statement. You can remove the ORDER BY clause, as it is not doing anything useful in your example.