SQL Column Value Within string - sql

I Have a string below
100Pipers22WoodfieldRoadBlackpoolFY16AX
I also have an address table on where i want to cross reference the postcode column to see if the value exists in the above string. Column value would be FY16AX which is visible in the string.
I cant seem to get a match.

If I understand correctly, you can use like. In standard SQL, this would look like:
where string like '%' || postcode
The || is the string concatenation operator. Some databases have their own operators or functions for this functionality.

Declare #vString nvarchar(50)
Set #vString = '100Pipers22WoodfieldRoadBlackpoolFY16AX'
Select Count(*) From tbl_Address Where Zip = right(#vString,6)
If the select statement returns a value greater than zero, you have a match.

Related

Use like '%' and match NULL values with NUMBER columns

This question is almost exactly like mine but none of the answers work with my case.
If it was my question I'd slightly edit it to make it a different question. This question is thus different from the linked one.
Here's the problem: I want a way to match any non-null value ('%') AND null values.
The thing is:
I'm using oracle so I can't use IsNull
Some columns are NUMBERs, which means I can't use COALESCE(column, ' '). (ORA-00932: inconsistent datatypes: expected NUMBER got CHAR). However, like '%' and like '2118' do work on NUMBER columns.
None of the answers apply to this problem because you can't make a null into an empty string when the column is a NUMBER.
How could I do to achieve this?
Some context:
My procedure takes a lot of parameters, and does a select with all of them. They can all have a value or be null, so if they're null they're replaced with '%'.
That way, the procedure does :
where t.col1 like param1
and t.col2 like param2
...
Most of the times, only one or two parameters is not null. For the others parameters, the procedure needs to match on every row.
But when the value is null, like '%' doesn't match the row. I'm looking for a way to match anything when param x is empty (so paramx = '%')
My procedure takes a lot of parameters, and does a select with all of them. They can all have a value or be null, so if they're null they're replaced with '%'.
That seems like you're making life hard for yourself. Leave them null, then do:
where (param1 is null or t.col1 like param1)
and (param2 is null or t.col2 like param2)
If param1 (the procedure argument; life is simpler when your parameter/variable names and column names are different... so I've changed the column names to make it a bit clearer) is null it is basically ignored* and all rows pass that part of the filter, whether the column value is null or not null. If param2 is not null then the is null check for that fails and only rows with (not-null) column values that match param2 value meet that part of the filter.
* Conditions in an or can be evaluated in any order; putting the is null check first doesn't necessarily mean the like won't be evaluated - but the optimiser is pretty smart about that sort of thing
If you want to match a specific value and NULL, you can use OR:
where col = <specific value> or col is null
In Oracle NVL can be used instead of ISNULL
IF NVL(aNumberColumn,-1) = -1 THEN
---whatever
END IF;
Oracle automatically converts NUMBER to VARCHAR2 for like-conditions. So what you have todo is do that yourself so you can use coalesce:
COALESCE(TO_CHAR(column), ' ') like '%'
The proposals from other answers based on OR or NVL/ COALESCE are "elegant" and simple, but as a rule they inhibit the index access, which is the most important thing.
You may step down to use dynamic SQL to address the optional parameter problem - which is your case. If a parameter is not passed (it is NULL) - simple ignore it.
So for example with two parameters, if both parameters are passed, generate following SQL
select * from tab t
where t.col1 like :param1
and t.col2 like :param2
If only parameter 1 is given, generate this SQL:
select * from tab t
where t.col1 like :param1
With no parameter you will end with
select * from tab t
Technically it is preferable to have in all SQL statements the same number of bind variables, which is not the case in the above proposal. See this answer for detailed explanation of the trick popularized by Tom Kyte to preserve the number of bind variable with optional parameters.
For example the second statement with only parameter 1 would yield following SQL
select * from tab t
where t.col1 like :param1
and (1=1 or t.col2 like :param2)
The shortcut logik of 1=1(which is TRUE) eliminates the second part of the predicate, but the bind variable is still used, so the number of the bind variables remains constant.
The big advantage is a fine index range access of this query

SQL WHERE is anything

I'm working on a database query via a search bar and would like it to sometimes yield all results (depending on what is inputted)
I know that for SELECT you can use * in order to select all columns. Is there similar SQL syntax: i.e. WHERE name IS * to essentially always be true?
Edit to clarify:
The nature of the clause is that a variable is used to set the name (I'm actually not able to change the clause, that was made clear). i.e. WHERE name IS [[inputName]] (inputName is the decided by the search bar)
WHERE ISNULL(name, '') = ISNULL(name, '')
(assuming that 'name' is of a string type)
Just make the column reference itself. However, if this is the only goal of your query, why are you against omitting the WHERE clause?
If you want to return all results in a SQL statement, you can simply omit the WHERE clause:
SELECT <* or field names> FROM <table>;
You should use WHERE only when you want to filter your data on a certain field. In your case you just don't want to filter at all.
Actually you don't need WHERE clause at all in this situation. But if you insist then you should write your predicate so it always returns true. This can be done many ways:
Any predicate like:
WHERE 1=1
With column:
WHERE name = name OR name is null
With LIKE:
WHERE name LIKE '%' OR name is null
With passed parameter:
WHERE name = #name OR #name is null
You can think of more of course. But I think you need the last one. Pass NULL from app layer if you want all rows.

Not getting expected result from sql query to find max value

I am trying to get max value from a table but it's not giving me the correct value (max value).
I used this query to get value
SELECT MAX(column_name1) FROM table_name WHERE column_name2 = 'some_value'
The data type of column_name is VARCHAR. Is this the problem for showing this unexpected result ?
I think this is due to data type. So please change the data type to int or float and try once.
Hmmm. The value would always be 'some_value'. If you want the max(), remove the where clause:
SELECT MAX(column_name)
FROM table_name;
The data type has nothing to do with the issue.
Then you would use:
SELECT MAX(salary)
FROM table_name
WHERE name = 'John';
EDIT:
If you store numbers and dates as character strings instead of using native SQL types, then you are bound to have problems. MySQL does have easy conversion from strings to numbers, so you can try this:
SELECT MAX(salary + 0)
FROM table_name
WHERE name = 'John';
But the real solution is to fix the data types.
MAX() function is used to be applied in integer value, not for varchar
I tried to cast that varchar into int and its working now. I changed the query like this -
SELECT MAX(CAST(column_name1 AS Int)) FROM table_name WHERE column_name2 = 'some_value'

How to md5 all columns regardless of type

I would like to create a sql query (or plpgsql) that will md5() all given rows regardless of type. However, below, if one is null then the hash is null:
UPDATE thetable
SET hash = md5(accountid || accounttype || createdby || editedby);
I am later using the hash to compare uniqueness so null hash does not work for this use case.
The problem was the way it handles concatenating nulls. For example:
thedatabase=# SELECT accountid || accounttype || createdby || editedby
FROM thetable LIMIT 5;
1Type113225
<NULL>
2Type11751222
3Type10651010
4Type10651
I could use coalesce or CASE statements if I knew the type; however, I have many tables and I will not know the type ahead of time of every column.
There is much more elegant solution for this.
In Postgres, using table name in SELECT is permitted and it has type ROW. If you cast this to type TEXT, it gives all columns concatenated together in string that is actually JSON.
Having this, you can get md5 of all columns as follows:
SELECT md5(mytable::TEXT)
FROM mytable
If you want to only use some columns, use ROW constructor and cast it to TEXT:
SELECT md5(ROW(col1, col2, col3)::TEXT)
FROM mytable
Another nice property about this solution is that md5 will be different for NULL vs. empty string.
Obligatory SQLFiddle.
You can also use something else similar to mvp's solution. Instead of using ROW() function which is not supported by Amazon Redshift...
Invalid operation: ROW expression, implicit or explicit, is not supported in target list;
My proposition is to use NVL2 and CAST function to cast different type of columns to CHAR, as long as this type is compatible with all Redshift data types according to the documentation. Below there is an example of how to achieve null proof MD5 in Redshift.
SELECT md5(NVL2(col1,col1::char,''),
NVL2(col2,col2::char,''),
NVL2(col3,col3::char,''))
FROM mytable
This might work without casting second NVL2 function argument to char but it would definately fail if you'd try to get md5 from date column with null value.
I hope this would be helpful for someone.
Have you tried using CONCAT()? I just tried in my PG 9.1 install:
SELECT CONCAT('aaaa',1111,'bbbb'); => aaaa1111bbbb
SELECT CONCAT('aaaa',null,'bbbb'); => aaaabbbb
Therefore, you can try:
SELECT MD5(CONCAT(column1, column2, column3, column_n)) => md5_hash string here
select MD5(cast(p as text)) from fiscal_cfop as p

Oracle 10g: column is blank, but is not null or an empty string

I have a column in a table that is blank. The weird thing is that it does not appear to be null or an empty string. So, if I do this:
SELECT *
FROM TABLE
WHERE column IS NULL
...or:
SELECT *
FROM TABLE
WHERE column = ''
I get nothing. Thoughts?
Issue this query:
SELECT column, DUMP(column, 1016)
FROM table
It'll show the exact contents.
Related: Oracle does not allow empty strings; they're silently converted to NULL.
Maybe the column contains only spaces?
Did you try
select *
from table
where trim(column) is null
Oracle's got a basically permanent annoyance that empty strings are treated as null. However, are you sure that's an empty string? It could be an otherwise invisible character, such as a space or tab/linebreak/linefeed/etc... What does the string length show when you do select length(column) from table?
Try this:
SELECT *
FROM TABLE
WHERE TRIM(column) IS NULL
If your column is not VARCHAR2 but CHAR(N) then insertion of an empty string is padded. See what Tom Kyte tells about this