I use Postgres 8.1. In my sub function I am returning a string which some ID s are concatenated together. And I need to split those ID s and use them in the WHERE clause from main select query.
for example sub function:
subFunction( 'item_id' character varying )RETURNS character varying AS
-- implementation of sub function---
return concatenatedString;
this concatenatedString like this: 23|32|25|234.
And in my main query
SELECT * FROM tableName WHERE id IN (--need to get ids returning from sub function splitting the string--) .
Is there any way that I can split the string returned by sub function and put the result into the IN clause.
Another approach to solve this : Split PostgreSQL Query filtering
As #JustBob says in his comments, your best bet would be to upgrade to a more recent postgresql version, after which you could use regexp_split_to_table, or regexp_split_to_array and then use array operators instead, eg.
SELECT * FROM tablename WHERE id = ANY (regexp_split_to_array(subFunction(...), '\|'));
However, luckily for you, your string resembles an alternation regex, so you might just be able to get away with this:
SELECT * FROM tablename WHERE id::text ~ '^(' || subFunction(...) || ')$';
This will do a regular expression match against a regex looking like this
^(23|32|25|234)$
which will return true if your id value is in the list.
That should work even in 8.1.
Related
Newbie here. Been searching for hours now but I can seem to find the correct answer or properly phrase my search.
I have thousands of rows (orderids) that I want to put on an IN function, I have to run a LIKE at the same time on these values since the columns contains json and there's no dedicated table that only has the order_id value. I am running the query in BigQuery.
Sample Input:
ORD12345
ORD54376
Table I'm trying to Query: transactions_table
Query:
SELECT order_id, transaction_uuid,client_name
FROM transactions_table
WHERE JSON_VALUE(transactions_table,'$.ordernum') LIKE IN ('%ORD12345%','%ORD54376%')
Just doesn't work especially if I have thousands of rows.
Also, how do I add the order id that I am querying so that it appears under an order_id column in the query result?
Desired Output:
Option one
WITH transf as (Select order_id, transaction_uuid,client_name , JSON_VALUE(transactions_table,'$.ordernum') as o_num from transactions_table)
Select * from transf where o_num like '%ORD12345%' or o_num like '%ORD54376%'
Option two
split o_num by "-" as separator , create table of orders like (select 'ORD12345' as num
Union
Select 'ORD54376' aa num) and inner join it with transf.o_num
One method uses OR:
WHERE JSON_VALUE(transactions_table, '$.ordernum') LIKE IN '%ORD12345%' OR
JSON_VALUE(transactions_table, '$.ordernum') LIKE '%ORD54376%'
An alternative method uses regular expressions:
WHERE REGEXP_CONTAINS(JSON_VALUE(transactions_table, '$.ordernum'), 'ORD12345|ORD54376')
According to the documentation, here, the LIKE operator works as described:
Checks if the STRING in the first operand X matches a pattern
specified by the second operand Y. Expressions can contain these
characters:
A percent sign "%" matches any number of characters or
bytes.
An underscore "_" matches a single character or byte.
You can escape "\", "_", or "%" using two backslashes. For example, "\%". If
you are using raw strings, only a single backslash is required. For
example, r"\%".
Thus , the syntax would be like the following:
SELECT
order_id,
transaction_uuid,
client_name
FROM
transactions_table
WHERE
JSON_VALUE(transactions_table,
'$.ordernum') LIKE '%ORD12345%'
OR JSON_VALUE(transactions_table,
'$.ordernum') LIKE '%ORD54376%
Notice that we specify two conditions connected with the OR logical operator.
As a bonus information, when querying large datasets it is a good pratice to select only the columns you desire in your out output ( either in a Temp Table or final view) instead of using *, because BigQuery is columnar, one of the reasons it is faster.
As an alternative for using LIKE, you can use REGEXP_CONTAINS, according to the documentation:
Returns TRUE if value is a partial match for the regular expression, regex.
Using the following syntax:
REGEXP_CONTAINS(value, regex)
However, it will also work if instead of a regex expression you use a STRING between single/double quotes. In addition, you can use the pipe operator (|) to allow the searched components to be logically ordered, when you have more than expression to search, as follows:
where regexp_contains(email,"gary|test")
I hope if helps.
I tried to run the following query:
select * from table where regexp_like('^{{', text_field)
And got the following error:
too big number for repeat range
Thinking perhaps regexp_like is confusing { for the repeat count operator, I also tried the following variations:
select * from table where regexp_like('^\{\{', text_field)
select * from table where regexp_like('^[{][{]', text_field)
select * from table where regexp_like('^[[:punct:]]{2}', text_field)
None of which worked. For now, text_field like '{{' suffices, but I may want to include a more flexible version of this that would require regular expressions. What's wrong with my approach here? And what does this error message mean?
You are using the prestodb regex_like function in the wrong way:
regexp_like(string, pattern)
Evaluates the regular expression pattern and determines if it is
contained within string. This function is similar to the LIKE
operator, expect that the pattern only needs to be contained within
string, rather than needing to match all of string. In other words,
this performs a contains operation rather than a match operation. You
can match the entire string by anchoring the pattern using ^ and $:
SELECT regexp_like('1a 2b 14m', '\d+b'); -- true
I require a select query that adds a space to the data based on the placement of the capital letters i.e. 'HelpMe' using this query would be displayed as 'Help Me' . Note i cannot use a stored function to do this the it must be done in the query itself. The Data is of variable length and query must be in SQL. Any Help will be appreciated.
Thanks
You need to use user defined function for this until MS give us support for regular expressions. Solution would be something like:
SELECT col1, dbo.RegExReplace(col1, '([A-Z])',' \1') FROM Table
Aldo this would produce leading space that you can remove with TRIM.
Replace regular expresion function:
http://connect.microsoft.com/SQLServer/feedback/details/378520
About dbo.RegexReplace you can read at:
TSQL Replace all non a-z/A-Z characters with an empty string
Assume if you are using Oracle RDBMS, you use the following,
REGEX_REPLACE
SELECT REGEXP_REPLACE('ILikeToWatchCSIMiami',
'([A-Z.])', ' \1')
AS RX_REPLACE
FROM dual
;
Managed to get this output: * SQLFIDDLE
But as you see it doesn't treat well on words such as CSI though.
I need to extract string from a value of a cell in Oracle table. How can I do that?
VALUE
--------
/var1/var2/var3/C751994ZP1QT11/var4.itp
I want to extract "C751994ZP1QT11" from the value using SQL. I searched some function like REGEXP_LIKE, but I am not quite understand how to use it.
Thanks ahead for the help.
If you want to extract a string, you need to use regexp_substr(). regexp_like() would return a boolean indicating if a certain regular expression matches your string, while regexp_substr() actually returns the matched string.
In your case, assuming you want the string between /** and **/, you could use something like this:
select
regexp_substr(
'/var1/var2/var3/**C751994ZP1QT11**/var4.itp',
'/\*\*.*\*\*/')
from dual
Refer here for some useful shortcuts on regular expressions with Oracle.
select REGEXP_REPLACE('/var1/var2/var3/**C751994ZP1QT11**/var4.itp','.*\*\*(.*)\*\*.*','\1') result from dual
How do I do this?
For example, if my column is "cats,dogs,birds" and I want to get any rows where column contains cats?
Using LIKE:
SELECT *
FROM TABLE
WHERE column LIKE '%cats%' --case-insensitive
While LIKE is suitable for this case, a more general purpose solution is to use instr, which doesn't require characters in the search string to be escaped. Note: instr is available starting from Sqlite 3.7.15.
SELECT *
FROM TABLE
WHERE instr(column, 'cats') > 0;
Also, keep in mind that LIKE is case-insensitive, whereas instr is case-sensitive.