SQL - can we combine AND operator and NOT IN? - sql

can we combine the AND operator and NOT IN in mysql? for example:
WHERE x AND y NOT IN ( SELECT X,Y
FROM ....
);
Is the syntax correct?

Whether or not this is possible depends on the database server you use. Some databases (eg PostgreSQL) support row values, which allow you to do this:
where (x, y) in (select colX, colY from ....)
Otherwise you can do something like
where exists (select 1 from ... where colX = x and colY = y)

yes but you should add "AND" operator to your query:
WHERE x AND y AND NOT IN ( SELECT X,Y FROM ....

Related

Select * From Table Where Name in like (wildcards)

Is it possible to combine SQL statements such as
SELECT * FROM X WHERE Y LIKE '%a%' OR Y LIKE '%b%' OR Y LIKE '%c%' OR Y LIKE '%d%'
with something like
SELECT * FROM X WHERE Y IN ('a', 'b', 'c', 'd')
so I don't have to write one big statement such as it is now:
IF NOT EXISTS(SELECT * FROM X WHERE Y LIKE '%a%' OR Y LIKE '%b%' OR Y LIKE '%c%' OR Y LIKE '%d%')
BEGIN
/* code */
END
Would be very nice to use something like SELECT * FROM X WHERE Y IN LIKE ('%a%', '%b%', etc..)
Appreciate all help and suggestions, thanks.
Please use the below code for your problem ,try and let me know if still there is issue.
SELECT * FROM X WHERE Y LIKE '%[a-d]%'
If your database supports RegEx, you can use that. For example:
SELECT * FROM X WHERE Y SIMILAR TO '%(a|b|c|d)%' in PostgreSQL, and
SELECT * FROM X WHERE Y REGEXP 'a|b|c|d' in MySQL.
LIKE '%[a-d]%' won't work because LIKEs in most databases don't accept regex patterns. This will just expect the literal text [a-d] somewhere in the string. How each database interprets regular expression (or native pattern) varies a lot. So you need to tailor these things to your database. For example, the following will not work in PostgreSQL:
SELECT * FROM X WHERE Y SIMILAR TO 'a|b|c|d'
because PostgreSQL will expect the whole string to be 'a', 'b', 'c', or 'd'.

Using WITH... AS (CTE) within a Postgres Function

in all the below descriptions, I have changed the names of variables, functions and datasets so as to make it easier for you to follow the code. What I want to do is create a new function, myFx, which takes in an argument of var_a and outputs a table with 3 columns - var_a, var_b and var_c.
The code is shown below, the bulk of which is a Common Table Expression (CTE) that uses UNION to combine the rows from three SELECT statements to make an interim table result, t_union. The lowermost chunk of code is the one which outputs what I desire through using t_union and self-joining it to itself.
While the paragraphs of code below work WITHOUT me typing the function parameters (CREATE OR REPLACE FUNCTION... and RETURNS TABLE...), once I add the function parameters in, I instead get an error indicating that I cannot use WITH as in (WITH t_union). Could anyone please advise me what the problem is here? Thanks so much!
CREATE OR REPLACE FUNCTION myFx (var_a varchar(2))
RETURNS TABLE (var_a varchar(2),
var_b character,
var_c character )
WITH t_union
AS (SELECT x, y, z,
RANK() OVER (PARTITION BY x ORDER BY (y COLLATE "C") ASC) AS stp_pos
FROM DATASET1
UNION ALL
SELECT x, y, z,
RANK() OVER (PARTITION BY x ORDER BY (y COLLATE "C") ASC) AS stp_pos
FROM DATASET2
UNION ALL
SELECT x, y, z,
RANK() OVER (PARTITION BY x ORDER BY (y COLLATE "C") ASC) AS stp_pos
FROM DATASET3
SELECT BS.atoc_code, L1.train_uid, L1.stp_indicator, L1.location AS loc1, L2.location AS loc2
FROM t_union L1 JOIN t_union L2
ON L1.x=L2.x AND L1.y<L2.y
JOIN DATASET3 BS ON L1.x=BS.x;
This is the error code I get:
ERROR: syntax error at or near "WITH"
LINE 9: WITH t_union
^
SQL state: 42601
Character: 197

SQL query with an OR clause and only one parameter

I was wondering if is there a way to do a query like this one (where Z is a variable)
SELECT * FROM table t WHERE t.X = Z OR t.Y = Z
writing only one time the Z. To be more specific I would like to do the same query like so
SELECT * FROM table t WHERE (t.X OR t.Y) = Z
I am using an Oracle DB and it (obviously) gives me an error when I try to execute it BUT I really like a way to do it like in the second query.
To make you know my situation X and Y are both VARCHAR2 and I already try something like
SELECT * FROM table t WHERE (t.X || t.Y) like '%Z%'
But, unluckily, it is not as accurate as the first one.
You can use in:
WHERE Z IN (t.X, t.Y)
Columns can be in the IN list as well as constants.
Try Like This
SELECT * FROM table t WHERE (t.X like %Z% OR t.Y like %Z% )

How to aggragate integers in postgresql?

I have a query that gives list of IDs:
ID
2
3
4
5
6
25
ID is integer.
I want to get that result like that in ARRAY of integers type:
ID
2,3,4,5,6,25
I wrote this query:
select string_agg(ID::text,',')
from A
where .....
I have to convert it to text otherwise it won't work. string_agg expect to get (text,text)
this works fine the thing is that this result should later be used in many places that expect ARRAY of integers.
I tried :
select ('{' || string_agg(ID::text,',') || '}')::integer[]
from A
WHERE ...
which gives: {2,3,4,5,6,25} in type int4 integer[]
but this isn't the correct type... I need the same type as ARRAY.
for example SELECT ARRAY[4,5] gives array integer[]
in simple words I want the result of my query to work with (for example):
select *
from b
where b.ID = ANY (FIRST QUERY RESULT) // aka: = ANY (ARRAY[2,3,4,5,6,25])
this is failing as ANY expect array and it doesn't work with regular integer[], i get an error:
ERROR: operator does not exist: integer = integer[]
note: the result of the query is part of a function and will be saved in a variable for later work. Please don't take it to places where you bypass the problem and offer a solution which won't give the ARRAY of Integers.
EDIT: why does
select *
from b
where b.ID = ANY (array [4,5])
is working. but
select *
from b
where b.ID = ANY(select array_agg(ID) from A where ..... )
doesn't work
select *
from b
where b.ID = ANY(select array_agg(4))
doesn't work either
the error is still:
ERROR: operator does not exist: integer = integer[]
Expression select array_agg(4) returns set of rows (actually set of rows with 1 row). Hence the query
select *
from b
where b.id = any (select array_agg(4)) -- ERROR
tries to compare an integer (b.id) to a value of a row (which has 1 column of type integer[]). It raises an error.
To fix it you should use a subquery which returns integers (not arrays of integers):
select *
from b
where b.id = any (select unnest(array_agg(4)))
Alternatively, you can place the column name of the result of select array_agg(4) as an argument of any, e.g.:
select *
from b
cross join (select array_agg(4)) agg(arr)
where b.id = any (arr)
or
with agg as (
select array_agg(4) as arr)
select *
from b
cross join agg
where b.id = any (arr)
More formally, the first two queries use ANY of the form:
expression operator ANY (subquery)
and the other two use
expression operator ANY (array expression)
like it is described in the documentation: 9.22.4. ANY/SOME
and 9.23.3. ANY/SOME (array).
How about this query? Does this give you the expected result?
SELECT *
FROM b b_out
WHERE EXISTS (SELECT 1
FROM b b_in
WHERE b_out.id = b_in.id
AND b_in.id IN (SELECT <<first query that returns 2,3,4,...>>))
What I've tried to do is to break down the logic of ANY into two separate logical checks in order to achieve the same result.
Hence, ANY would be equivalent with a combination of EXISTS at least one of the values IN your list of values returned by the first SELECT.

Make table or database to be case insensitive

If I make a search for instance
"Candy" in where statement I retrieve 12 hits however if I write "candy" I retrieve 0 hits.
Is it possible to make the database or table to be case insensitive?
If yes, how?
Thank you
A simple solution might be to convert both the search string and the column you are searching on to lowercase using the LOWER() function in SQL Server. Something like:
SELECT whatever
FROM yourTable
WHERE LOWER(whatever) = LOWER(#searchString)
If you want to make your where clause case insensitive . convert left and right to the same case and then put condition .
If I take table as mytable with attributes X and Y . where filter is on Y then
select X , Y from mytable where UPPER(Y) = UPPER(#toSearch)
or
`select X , Y from mytable where LOWER(Y) = LOWER(#toSearch)`
In your case, maybe its easier to understand if i use your where clause ,example:
SELECT *
FROM yourTable
WHERE LOWER(whatever) = 'candy' or
SELECT *
FROM yourTable
WHERE UPPER(whatever) = 'CANDY'