MSAccess - SQL query everything to the right OR left of a character - sql

Using Ms Access 2016 I'm trying to run a SELECT query to match strings on a column from table1 and table2. I can do this with the following:
SELECT *
FROM table1 AS a, table2 AS b
WHERE a.luCode LIKE b.Code
table1.luCode only eve rhas one code, however, table2.Code sometimes has two codes in it separated by ";":
table2.Code
--------------------
someCode1
someCode2
someCode3;someCode4
someCode5
How can I perform the above query checking both to the left and right of the ";"?
So far I've been trying to use InStr (just to the left) using:
SELECT *
FROM table1 AS a, table2 AS b
WHERE a.luCode LIKE LEFT(b.Code,(InStr(1,b.Code,";"))-1);
But I get a datatype mismatch.
Figuring this would be either "null" values of empty strings (after checking it seems it's empty strings) I can add an IIF statement:
SELECT *
FROM table1 AS a, table2 AS b
WHERE IIF(b.Code<>"",a.luCode LIKE LEFT(b.Code,(InStr(1,b.Code,";"))-1));
This throws an "invalid procedure call" error.
I could just make a new column with the data after the ";" but there must be a way to do this with InStr.

First, this is a really, really bad data format. You should have a table with one row for each code, instead of throwing them together in a string.
Sometimes, we are stuck with other people's bad design decisions. In this case, you can try:
WHERE ';' & b.luCode & ';' LIKE '*;' & a.Code & ';*'
Or alternatively use instr() with the same logic.

Related

comparing column values in SQL

I am working on multiple tables in PostgreSQL and I want to compare the column values of two tables but one of them is written differently here is how
it's the same values but one of them starts with three Zeros.
I've tried this
select * from table1, table2
where table1.projectid=table2.project_id and operating_unit= 'USA'
I even tries to replace '=' with 'IN' but both return an empty table
Your code should work if one of the values is a number. But neither are. How about converting them?
select *
from table1 join
table2
on table1.projectid::numeric = table2.project_id::numeric and
operating_unit = 'USA';
Sadly, having to convert on both ends precludes the use of indexes. So an alternative is to just change one side or the other:
select *
from table1 join
table2
on '000' || table1.projectid] = table2.project_id and
operating_unit = 'USA';
At least this makes it possible to use an index.

SQL UPDATE part of a string with value from other table

I need to replace part of a string with a value from another database table. Actually I need to replace the userids with emails.
DB1.TABLE1
ID|EMAIL
1 |johndoe; janedoe;
2 |otherguy; johndoe;
DB2.TABLE2
ID|USERID |EMAIL
1 |johndoe |johndoe#test.com
2 |janedoe |janedoe#test.com
3 |otherguy|otherguy#test.com
my query
UPDATE
TABLE1
set
EMAIL = TABLE2.EMAIL
from
DB2.TABLE2
where
TABLE1.EMAIL = TABLE2.USERID
How can I specify the "part of the string" thing ?
There are a number of comments about changing your schema...which would be the best way forward.
It looks like what you are storing in table1.email is actually a list of UserId from table2. So you'll need to break out these ids in order to join to the tables together.
If you absolutely must follow this path, then there are existing Q+As on the site that will help you:
(I've taken a leap of faith that you are using SQL server ... but if you search I'm sure you can find similar answers for other RDBMSs)
Turning a Comma Separated string into individual rows
and
Multiple rows to one comma separated value
I guess you need the following
UPDATE TABLE1
SET EMAIL = (
SELECT TABLE2.EMAIL
FROM TABLE2
WHERE TABLE1.EMAIL LIKE TABLE2.USERID + '%');
demo

Mass criteria query

I have an Access query. I need a mass 'like' criteria.
Normally it's "Like "Apple" or "Orange"". However, I have over 400 words.
How do make this happen without manually typing in a Like formula by hand with the 400 words?
Is there a way to do this by referencing a table or form?
As for "referencing a table", you can actually do a join using LIKE instead of =.
SELECT
t.*
FROM
target t
INNER JOIN
SearchList s
ON t.name LIKE '%' + s.term '%'
In this case, SearchList is a table you create just for this task with just 1 column containing the terms you want to search for.
You can use in clause , sub query to get result, the query in Access can have 64000 characters so your 400 words X 5 chars in each approximate , 2000 chars + 50 chars SQL statement, should be OK,
Select * from tblVitalInfo where ObjectName in ('Apple','Banana','Pitch')
But I will recommend following better way of doing same,
Assume the table tblVitalInfo(ID, ObjectName) , and searching ObjectName
I would create a table tblWordList(ID autonumber primary key, SearchString Text(200)) . Write Insert statement to add all the words to search e.g. Insert into tblWordList(SearchString) values('Apple') ; execute these queries in Access. OR you can open the table to add data , easier than insert statement.
Run the following query
Select * from tblVitalInfo where ObjectName in (Select SearchString tblWordList)

Compare comma separated list with individual row in table

I have to compare comma separated values with a column in the table and find out which values are not in database. [kind of master data validation]. Please have a look at the sample data below:
table data in database:
id name
1 abc
2 def
3 ghi
SQL part :
Here i am getting comma separated list like ('abc','def','ghi','xyz').
now xyz is invalid value, so i want to take that value and return it as output saying "invalid value".
It is possible if i split those value, take it in temp table, loop through each value and compare one by one.
but is there any other optimal way to do this ??
I'm sure if I got the question right, however, I would personally be trying to get to something like this:
SELECT
D.id,
CASE
WHEN B.Name IS NULL THEN D.name
ELSE "invalid value"
END
FROM
data AS D
INNER JOIN badNames B ON b.Name = d.Name
--as SQL is case insensitive, equal sign should work
There is one table with bad names or invalid values if You prefer. This can a temporary table as well - depending on usage (a black-listed words should be a table, ad hoc invalid values provided by a service should be temp table, etc.).
NOTE: The select above can be nested in a view, so the data remain as they were, yet you gain the correctness information. Otherwise I would create a cursor inside a function that would go through the select like the one above and alter the original data, if that is the goal...
It sounds like you just need a NOT EXISTS / LEFT JOIN, as in:
SELECT tmp.InvalidValue
FROM dbo.HopeThisIsNotAWhileBasedSplit(#CSVlist) tmp
WHERE NOT EXISTS (
SELECT *
FROM dbo.Table tbl
WHERE tbl.Field = tmp.InvalidValue
);
Of course, depending on the size of the CSV list coming in, the number of rows in the table you are checking, and the style of splitter you are using, it might be better to dump the CSV to a temp table first (as you mentioned doing in the question).
Try following query:
SELECT SplitedValues.name,
CASE WHEN YourTable.Id IS NULL THEN 'invalid value' ELSE NULL END AS Result
FROM SplitedValues
LEFT JOIN yourTable ON SplitedValues.name = YourTable.name

Can I use a table column name as a search argument in db2 "like" or "contain" operator/function

I have two tables: one containing a column (Description) that I would like to search using values in a column (keyword) in another table. I would like to perform something like
select table1.description, tabl2.keyword,
case when
table1.description like `'''%'||table2.keyword||'%''' then 1
-- or contains(table1.description, table2.keyword)
else
0
end
as found
from table1, table2
The documentation for Contain function seems to indicate that the search parameter (table2.keyword in my case) has to be a constant (I suspect "like" also has similar constraints).
The error messages I get seem to indicate this constraint.
Is there a solution that I can use?
You can do it with like. Your query should work:
select table1.description, tabl2.keyword,
(case when table1.description like '''%'||table2.keyword||'%'''
then 1 else 0
end) as found
from table1 cross join table2;
I prefer explicit joins, cross join instead of ,.