SQL query with CONCAT LIKE AND - sql

I have an query like this:
SELECT * FROM `tbl_shop`
WHERE
(LOWER (CONCAT(address, name)) LIKE (LOWER ('%boston%')) AND
LOWER (CONCAT(address, name)) LIKE (LOWER('%smoke%')));
My question is simple - is there any way how to write this code without need to repeat CONCAT(address, name) part?
I tried
SELECT * FROM `tbl_shop`
WHERE
(LOWER (CONCAT(address, name)) LIKE (LOWER ('%boston%')) AND (LOWER('%smoke%')));
But this was not giving any results. I simply need all results, which contain both words. I can not use full text, because I am using inno db and want to keep it.
Thanks in advance.

You can do
SELECT b.* FROM
(
SELECT a.*, LOWER(CONCAT(a.address, a.name)) AS field_to_check
)b
WHERE b.field_to_check LIKE (LOWER ('%boston%'))
AND b.field_to_check LIKE (LOWER('%smoke%'));
However, it's just syntax sugar, and it shouldn't be a difference in performance.

Related

How can query be optimized?

I have a simple select query on a table, but with different values in LIKE operator. Query is as follows:
SELECT *
FROM BatchServices.dbo.TaskLog
WHERE EntryTime BETWEEN '20190407' AND '20190408' AND
TaskGroup LIKE '%CSR%' AND
(LogText LIKE '%error%' OR LogText LIKE '%fail%')
This above query is fine and returning me the expected results but I don't want to have multiple LIKE in a query, so I have already tried something like
SELECT *
from BatchServices.dbo.TaskLog
WHERE taskgroup = 'csr' AND
LogText IN ( '%error%','%fail%') AND
EntryTime>'2019-04-07'
ORDER BY EntryTime ASC
This query is not giving me any results.
I am expecting a query which looks smarter than the one I have which returns result. Any help?
use like operator with OR condition
SELECT * from BatchServices.dbo.TaskLog WHERE taskgroup ='csr' AND
(LogText like '%error%' or LogText like '%fail%')
AND EntryTime>'2019-04-07'
ORDER BY EntryTime ASC
The LIKE operators are not the problem. It's the leading wild cards. Unless you cant get rid of those, your optimization options are going to be limited to making sure you have a covering index on EntryTime... That and replacing the "*" with the specific columns you need.

using select count based on partial data

I'm currently making a call to an SQL database that counts all entries where the cell starts with NOI, but ends with anything else.
I thought using the below would work, but it doesn't seem to, anyone have any ideas? I know the % sign is the wildcard for foxpro, I don't know if this is the same in SQL
SELECT COUNT * FROM DIARY WHERE PTNOTE = 'NOI%'
You have to use LIKE if you want to use the wildcard characters:
SELECT COUNT(*) FROM DIARY WHERE PTNOTE LIKE 'NOI%'
(also added the parantheses around *)
You are missing parentheses:
SELECT COUNT(*)
FROM DIARY
WHERE PTNOTE = 'NOI%';
It is not the case even in Foxpro. You should use parentheses and "like":
SELECT COUNT(*) FROM DIARY WHERE PTNOTE like 'NOI%'

select count(distinct) where col not like ('%d1,%d2,...')

select
count(distinct [PROV_CT])
from
[HRecent]
where
[PROV_CT] not like ('%P125, %P961, %P160, %P960, %P220, %P004')
Can I write a query like this? Actually it is showing outputs which is different from the query output.
select
count(distinct [PROV_CT])
from
[HRecent]
where
[PROV_CT] not like '%P125' and
[PROV_CT] not like '%P220' and
[PROV_CT] not like '%P960' and
[PROV_CT] not like '%P004' and
[PROV_CT] not like '%P961' and
[PROV_CT] not like '%P160'
Can anyone help me out please? I want to write an optimised query.
You cannot write the query using a single string literal like in:
[PROV_CT] not like ('%P125, %P961, %P160, %P960, %P220, %P004')
This predicate doesn't look for separate values like '%P125', '%P961' etc.
If you have a very big list of values against which NOT LIKE operation is to be performed, then it might be simpler to do it like this:
select
count(distinct [PROV_CT])
from
[HRecent]
cross apply (
select count(*)
from (values ('%P125'), ('%P961'),
('%P160'), ('%P960'),
('%P220'), ('%P004') ) AS t(v)
where [PROV_CT] LIKE t.v) AS x(cnt)
where x.cnt = 0
Using VALUES Table Value Constructor you create an in-line table containing all the values against which [PROV_CTRCT] column is to be compared. Then query this table using a single LIKE operation to find if there is a match or not.
Demo here

How can I SELECT DISTINCT on the last, non-numerical part of a mixed alphanumeric field?

I have a data set that looks something like this:
A6177PE
A85506
A51SAIO
A7918F
A810004
A11483ON
A5579B
A89903
A104F
A9982
A8574
A8700F
And I need to find all the ENDings where they are non-numeric. In this example, that means PE, AIO, F, ON, B and F.
In pseudocode, I'm imagining I need something like
SELECT DISTINCT X FROM
(SELECT SUBSTR(COL,[SOME_CLEVER_LOGIC]) AS X FROM TABLE);
Any ideas? Can I solve this without learning regexp?
EDIT: To clarify, my data set is a lot larger than this example. Also, I'm only interested in the part of the string AFTER the numeric part. If the string is "A6177PE" I want "PE".
Disclaimer: I don't know Oracle SQL. But, I think something like this should work:
SELECT DISTINCT X FROM
(SELECT SUBSTR(COL,REGEXP_INSTR(COL, "[[:ALPHA:]]+$")) AS X FROM TABLE);
REGEXP_INSTR(COL, "[[:ALPHA:]]+$") should return the position of the first of the characters at the end of the field.
For readability, I'd recommend using the REGEXP_SUBSTR function (If there are no performance issues of course, as this is definitely slower than the accepted solution).
...also similar to REGEXP_INSTR, but instead of returning the position of the substring, it returns the substring itself
SELECT DISTINCT SUBSTR(MY_COLUMN,REGEXP_SUBSTR("[a-zA-Z]+$")) FROM MY_TABLE;
(:alpha: is supported also, as #Audun wrote )
Also useful: Oracle Regexp Support (beginning page)
For example
SELECT SUBSTR(col,INSTR(TRANSLATE(col,'A0123456789','A..........'),'.',-1)+1)
FROM table;

Return rows where first character is non-alpha

I'm trying to retrieve all columns that start with any non alpha characters in SQlite but can't seem to get it working. I've currently got this code, but it returns every row:
SELECT * FROM TestTable WHERE TestNames NOT LIKE '[A-z]%'
Is there a way to retrieve all rows where the first character of TestNames are not part of the alphabet?
Are you going first character only?
select * from TestTable WHERE substr(TestNames,1) NOT LIKE '%[^a-zA-Z]%'
The substr function (can also be called as left() in some SQL languages) will help isolate the first char in the string for you.
edit:
Maybe substr(TestNames,1,1) in sqllite, I don't have a ready instance to test the syntax there on.
Added:
select * from TestTable WHERE Upper(substr(TestNames,1,1)) NOT in ('A','B','C','D','E',....)
Doesn't seem optimal, but functionally will work. Unsure what char commands there are to do a range of letters in SQLlite.
I used 'upper' to make it so you don't need to do lower case letters in the not in statement...kinda hope SQLlite knows what that is.
try
SELECT * FROM TestTable WHERE TestNames NOT LIKE '[^a-zA-Z]%'
SELECT * FROM NC_CRIT_ATTACH WHERE substring(FILENAME,1,1) NOT LIKE '[A-z]%';
SHOULD be a little faster as it is
A) First getting all of the data from the first column only, then scanning it.
B) Still a full-table scan unless you index this column.