Access SQL Query: trouble with * wildcard in WHERE AND LIKE statement - sql

The query I'd like to execute:
SELECT *
FROM qryReportView
WHERE ((ID = 719)
AND (Name Like "*x"));
However when I run this query I get no records returned. Each criterion works on its own:
SELECT *
FROM qryReportView
WHERE ID = 719;
and
SELECT *
FROM qryReportView
WHERE Name Like "*x";
Both queries return records as expected but when I combine them something goes wrong. I know there is at least one record for which both criteria are true.
NOTE: When I replace the * wildcard with an explicit name, I get the correct record returned. This is not a viable solution for me though because my query needs to select records ending in "x" with a number of possible prefixes.
Thank you so much for the help.

Your issue is a logical operator issue.
When you ask an RDBMs for a samich and a coke, if it has a samich but not a coke, you get nothing. Which is what is happening here, you need an 'or'
SELECT *
FROM qryReportView
WHERE (ID = 719
OR
Name Like '*x');

Related

SQL: Return records containing a word where the last letter is anything except K

Suppose I have a table containing a column by the name "Query". I have to display the records where the string in this column has used noloc instead of nolock. Note that noloc can be followed/preceded by ) or space etc. I just need all records that have anything before and after noloc except nolock. Is there a way to do it in SQL?
I tried:
select * from table1
where Query LIKE '%noloc%'
but this includes queries containing nolock. I tried variations of the above like putting space before and/or after % but none of them fills all the criteria.
You can use both conditions in the where clause
select * from table1
where Query LIKE '%noloc%' and Query NOT LIKE '%nolock%'
You want anything + noloc + any one char but k + anything. Here:
select * from table1
where Query LIKE '%noloc[^k]%'

Using CONTAINS to find items IN a table

I'm trying to write a SP that will allow users to search on multiple name strings, but supports LIKE functionality. For example, the user's input might be a string 'Scorsese, Kaurismaki, Tarkovsky'. I use a split function to turn that string into a table var, with one column, as follows:
part
------
Scorsese
Kaurismaki
Tarkovsky
Then, normally I would return any values from my table matching any of these values in my table var, with an IN statement:
select * from myTable where lastName IN (select * from #myTableVar)
However, this only returns exact matches, and I need to return partial matches. I'm looking for something like this, but that would actually compile:
select * from myTable where CONTAINS(lastName, select * from #myTableVar)
I've found other questions where it's made clear that you can't combine LIKE and IN, and it's recommended to use CONTAINS. My specific question is, is it possible to combine CONTAINS with a table list of values, as above? If so, what would that syntax look like? If not, any other workarounds to achieve my goal?
I'm using SQL Server 2016, if it makes any difference.
You can use EXISTS
SELECT * FROM myTable M
WHERE
EXISTS( SELECT * FROM #myTableVar V WHERE M.lastName like '%'+ V.part +'%' )
Can your parser built the entire statement? Will that get you what you want?
select *
from myTable
where CONTAINS
(lastName,
'"Scorsese" OR "Kaurismaki" OR "Tarkovsky"'
)
This can be done using CHARINDEX function combined with EXISTS:
select *
from myTable mt
where exists(select 1 from #myTableVar
where charindex(mt.lastName, part) > 0
or charindex(part, mt.lastName) > 0)
You might want to omit one of the conditions in the inner query, but I think this is what you want.

SQL Server where column in where clause is null

Let's say that we have a table named Data with Id and Weather columns. Other columns in that table are not important to this problem. The Weather column can be null.
I want to display all rows where Weather fits a condition, but if there is a null value in weather then display null value.
My SQL so far:
SELECT *
FROM Data d
WHERE (d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%' OR d.Weather IS NULL)
My results are wrong, because that statement also shows values where Weather is null if condition is not correct (let's say that users mistyped wrong).
I found similar topic, but there I do not find appropriate answer.
SQL WHERE clause not returning rows when field has NULL value
Please help me out.
Your query is correct for the general task of treating NULLs as a match. If you wish to suppress NULLs when there are no other results, you can add an AND EXISTS ... condition to your query, like this:
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
OR (d.Weather IS NULL AND EXISTS (SELECT * FROM Data dd WHERE dd.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'))
The additional condition ensures that NULLs are treated as matches only if other matching records exist.
You can also use a common table expression to avoid duplicating the query, like this:
WITH cte (id, weather) AS
(
SELECT *
FROM Data d
WHERE d.Weather LIKE '%'+COALESCE(NULLIF('',''),'sunny')+'%'
)
SELECT * FROM cte
UNION ALL
SELECT * FROM Data WHERE weather is NULL AND EXISTS (SELECT * FROM cte)
statement show also values where Wether is null if condition is not correct (let say that users typed wrong sunny).
This suggests that the constant 'sunny' is coming from end-user's input. If that is the case, you need to parameterize your query to avoid SQL injection attacks.

TSQL NOT EXISTS Why is this query so slow?

Debugging an app which queries SQL Server 05, can't change the query but need to optimise things.
Running all the selects seperately are quick <1sec, eg: select * from acscard, select id from employee... When joined together it takes 50 seconds.
Is it better to set uninteresting accesscardid fields to null or to '' when using EXISTS?
SELECT * FROM ACSCard
WHERE NOT EXISTS
( SELECT Id FROM Employee
WHERE Employee.AccessCardId = ACSCard.acs_card_number )
AND NOT EXISTS
( SELECT Id FROM Visit
WHERE Visit.AccessCardId = ACSCard.acs_card_number )
ORDER by acs_card_id
Do you have indexes on Employee.AccessCardId, Visit.AccessCardId, and ACSCard.acs_card_number?
The SELECT clause is not evaluated in an EXISTS clause. This:
WHERE EXISTS(SELECT 1/0
FROM EMPLOYEE)
...should raise an error for dividing by zero, but it won't. But you need to put something in the SELECT clause for it to be a valid query - it doesn't matter if it's NULL or a zero length string.
In SQL Server, NOT EXISTS (and NOT IN) are better than the LEFT JOIN/IS NULL approach if the columns being compared are not nullable (the values on either side can not be NULL). The columns compared should be indexed, if they aren't already.

Is there a way to use a wildcard in a "where" statment for MySQL?

I have a query that uses a where clause. At times, this may be used and at others, I may want to omit it completely to get back all results. I can certainly write two different queries but I would like to cut down on any code that I can for simplistic reasons. Is there a way to do this in mysql?
Take a query like:
SELECT * FROM my_table WHERE id = '3'
and:
SELECT * FROM my_table
Is there a way to use the top query and still get back all records?
No, because the predicate in the first query may not actually retrieve all of the records from the table; it may use an index so that it only has to obtain the specific record(s) the query needs to return.
If you wanted to keep a predicate of that same form but still return all of the results, you would need to do something like this:
where id = 3 or id <> 3
or this:
where id = id
Note that to either of these, you'll have to add or id is null if id can be null.
If you just want to have a predicate in your query, this will suffice:
where 1
but this is just redundant, and you may as well just leave the predicate out.
More food for thought...
I notice you quoted the '3'. If your ids are char data you could use the LIKE string comparison operator.
For a single value
SELECT * FROM my_table WHERE id LIKE '3'
For all values
SELECT * FROM my_table WHERE id LIKE '%'
Won't give you any values with NULL id though.
If I understand your question correctly, then YES
SELECT * FROM my_table WHERE 1=1
If you're building the SQL query as you go along, and you decide at the last minute that you want to negate/ignore the "WHERE" part of your query, you can append OR 1 to your where-clause. Remember that logically, X OR TRUE is true for all X.
sqlite> SELECT id FROM moz_downloads WHERE id < 405 LIMIT 10;
80
403
404
sqlite> SELECT id FROM moz_downloads WHERE id < 405 OR 1 LIMIT 10;
80
403
404
405
407
408
409
410
411
412
Note that I had to stick a LIMIT 10 in there to not get too many results for the demonstration, but the second statement's where-clause is id < 405 or 1.
It depends on the application, but you may or may not generate your queries at runtime. Some queries will always be the same, like SELECT * FROM recent_files, but some queries will be like generated on-the-fly. In the latter case, you might have something like
something = make_safe_for_sql(get_something_from_user())
query = "SELECT * FROM data WHERE something=" + something
if should_ignore_something:
query += " OR 1"
database.execute(query)
Note: Depending on your SQL engine, you might need to do OR 1=1 to evaluate to a boolean true.
Your question is dubious. You are really saying that when there is no id==3 all entries should be returned. You can do that easily if you pull all entries and then sort them out using php:
$sql = mysql_query("SELECT * FROM my_table");
while($row = mysql_fetch_array($sql) {
if($row['id']==3)
// do something
}
But as the table grows this will put an enormous stress on the database. You should go with the multiple query and enforce some kind of limit on the second query.
// try to get id == 3
SELECT * FROM my_table
// if id == 3 returns 0 results
SELECT * FROM my_table LIMIT 5
Hope it helps!
You'd have to be using dynamic SQL, like
"SELECT * FROM my_table WHERE id " &
qualifier
Then set qualifier to "= '3'" or to "1".