How to "search" with a string of values for records whose columns contain said values - sql

Okay, I'm going to try to explain this as simply as I can.
Say I have 3 records of a certain table. We will call this table Objs, and Objs have an attribute, of type string, called colors (notice how it's plural). Here are the 3 hypothetical records in the database and their corresponding colors values:
obj1 colors: "red, green, blue"
obj2 colors: "blue, orange, yellow, green"
obj3 colors: "teal, purple"
Okay, so now say I want to be able find a subset of the records that have something in common (a good situation to use the WHERE method right?) However, I HAVE to be able to support searching for these records using either single or even multiple values. For instance:
Say my query is, "red, green".
Then the resulting collection of records would need to be obj1, and obj2 since their color values include the keywords "red" and "green".
Say my query is, "blue, purple".
The resulting collection should include obj1, obj2, and obj3.
Also, the format of the query and the attributes of Obj will be the values delimited with a ", " since the attributes and the query itself are generated by an array. I.e., the attributes of the object and the queries themselves will always have this format:
"value1, value2, value3, value4"
It will never be like this:
"value1 value2 value3 value4"
or any other possible format.
Thanks for all the help.

You could compare the value, treating it as an array, against another array. For example:
SELECT *
FROM example
WHERE string_to_array(colors,', ') && array['red','blue'];
The && operator here checks for overlaps.
Disclosure: I am an EnterpriseDB (EDB) employee.

Let's wrap it into function,
first of all we are creating array from search string to know how many or queries we need,
then we are preparing query,
and as a final step we are passing our query and search words to our model
def search_function(search_string)
names_array = search_string.split(', ')
query = 'name LIKE ?'
number_of_ors = names_array.count
number_of_ors.times do
query += ' OR name LIKE ?'
end
Objects.where(query, *names_array)
end

Related

Adding column to table based on whether another column = a specific string

I want to add a column called "Sweep" that contains bools based on whether the "Result" was a sweep or not. So I want the value in the "Sweep" column to be True if the "Result" is '4-0' or '0-4' and False if it isn't.
This is a part of the table:
I tried this:
ALTER TABLE "NBA_finals_1950-2018"
ADD "Sweep" BOOL;
UPDATE "NBA_finals_1950-2018"
SET "Sweep" = ("Result" = '4-0' OR "Result" = '0-4');
But for some reason, when I run this code...:
SELECT *
FROM "NBA_finals_1950-2018"
ORDER BY "Year";
...only one of the rows (last row) has the value True even though there are other rows where the result is a sweep ('4-0' or '0-4') as shown in the picture below.
I don't know why this is happening but I guess there is something wrong with the UPDATE...SET code. Please help.
Thanks in advance.
NOTE: I am using PostgreSQL 13
This would occur if the strings are not really what they look like -- this is often due to spaces at the beginning or end. Or perhaps to hyphens being different, or other look-alike characters.
You just need to find the right pattern. So so with a select. This returns no values:
select *
from "NBA_finals_1950-2018"
where "Result" in ('4-0', '0-4');
You can try:
where "Result" like '%0-4%' or
"Result" like '%4-0%'
But, this should do what you want:
where "Result" like '%4%' and
"Result" like '%0%'
because the numbers are all single digits.
You can incorporate this into the update statement.
Note: double quotes are a bad idea. I would recommend creating tables and columns without escaping the names.

Redshift - Pulling the right most value from cell

I have a columns with list of fruit names. I am trying to extract the right most value from the cell. Cell can have one value or n values. In which case, I am expecting to pull the last value.
Given below sample shows the actual value (col name: name_of_fruits) and the expected value (col name: expected_value )
name_of_fruits, expected_value
apples|oranges, oranges
apples|bananas, bananas
apples, apples
apples|mango|pears, pears
I tried performing the below code:
select name_of_fruits, right((name_of_fruits),position('|' in reverse(name_of_fruits))-1) as expected_value from table
I get an error SQL Error Invalid operation : Invalid length (context : Negative value given)
Could anyone assist to pull the required values. Thanks
I am using Redshift DB.
Try using REGEXP_REPLACE:
SELECT
name_of_fruits,
REGEXP_REPLACE(name_of_fruits, '.*|', '') AS expected_value
FROM yourTable;
The pattern .*| works nicely here, because in the case of a name string which does have more than one fruit, it would strip everything off leaving only the final fruit. And, in the case of a name string having only one name, the replacement would just no-op, also leaving the same fruit name.

Check subset using either string or array in Impala

I have a table like this
col
-----
A,B
The col could be string with comma or array. I have flexibility on the storage.
How to check of col is a subset of either another string or array variable? For example:
B,A --> TRUE (order doesn't matter)
A,D,B --> TRUE (other item in between)
A,D,C --> FALSE (missing B)
I have flexibility on the type. The variable is something I cannot store in a table.
Please let me know if you have any suggestion for Impala only (no Hive).
Thanks
A not pretty method, but perhaps a starting point...
Assuming a table with a unique identifier column id and an array<string> column col, and a string variable with ',' as a separator (and no occurrences of escaped '\,')...
SELECT
yourTable.id
FROM
yourTable,
yourTable.col
GROUP BY
yourTable.id
HAVING
COUNT(DISTINCT CASE WHEN find_in_set(col.item, ${VAR:yourString}) > 0 THEN col.item END)
=
LENGTH(regexp_replace(${VAR:yourString},'[^,]',''))+1
Basically...
Expand the arrays in your table, to one row per array item.
Check if each item exists in your string.
Aggregate back up to count how many of the items were found in the string.
Check that the number of items found is the same as the number of items in the string
The COUNT(DISTINCT <CASE>) copes with arrays like {'a', 'a', 'b', 'b'}.
Without expanding the string to an array or table (which I don't know how to do) you're dependent on the items in the string being unique. (Because I'm just counting commas in the string to find out how many items there are...)

Coldfusion Query of Queries with Empty Strings

The query I start out with has 40,000 lines of empty rows, which stems from a problem with the original spreadsheet from which it was taken.
Using CF16 server
I would like to do a Query of Queries on a variably named 'key column'.
In my query:
var keyColumn = "Permit No."
var newQuery = "select * from source where (cast('#keyColumn#' as varchar) <> '')";
Note: the casting comes from this suggestion
I still get all those empty fields in there.
But when I use "City" as the keyColumn, it works. How do the values in both those columns differ when they both say [empty string] on the query dump?
Is it a problem with column names? What kind of data are in those cells?
where ( cast('Permit No.' as varchar) <> '' )
The problem is the SQL, not the values. By enclosing the column name in quotes, you are actually comparing the literal string "P-e-r-m-i-t N-o-.", not the values inside that column. Since the string "Permit No." can never equal an empty string, the comparison always returns true. That is why the resulting query still includes all rows.
Unless it was fixed in ColdFusion 2016, QoQ's do not support column names containing invalid characters like spaces. One workaround is to use the "columnNames" attribute to specify valid column names when reading the spreadsheet. Failing that, another option is to take advantage of the fact that query columns are arrays and duplicate the data under a valid column name: queryAddColumn(yourQuery, "PermitNo", yourQuery["Permit No."]) (Though the latter option is less ideal because it may require copying the underlying data internally):

Problem with MySQL Select query with "IN" condition

I found a weird problem with MySQL select statement having "IN" in where clause:
I am trying this query:
SELECT ads.*
FROM advertisement_urls ads
WHERE ad_pool_id = 5
AND status = 1
AND ads.id = 23
AND 3 NOT IN (hide_from_publishers)
ORDER BY rank desc
In above SQL hide_from_publishers is a column of advertisement_urls table, with values as comma separated integers, e.g. 4,2 or 2,7,3 etc.
As a result, if hide_from_publishers contains same above two values, it should return only record for "4,2" but it returns both records
Now, if I change the value of hide_for_columns for second set to 3,2,7 and run the query again, it will return single record which is correct output.
Instead of hide_from_publishers if I use direct values there, i.e. (2,7,3) it does recognize and returns single record.
Any thoughts about this strange problem or am I doing something wrong?
There is a difference between the tuple (1, 2, 3) and the string "1, 2, 3". The former is three values, the latter is a single string value that just happens to look like three values to human eyes. As far as the DBMS is concerned, it's still a single value.
If you want more than one value associated with a record, you shouldn't be storing it as a comma-separated value within a single field, you should store it in another table and join it. That way the data remains structured and you can use it as part of a query.
You need to treat the comma-delimited hide_from_publishers column as a string. You can use the LOCATE function to determine if your value exists in the string.
Note that I've added leading and trailing commas to both strings so that a search for "3" doesn't accidentally match "13".
select ads.*
from advertisement_urls ads
where ad_pool_id = 5
and status = 1
and ads.id = 23
and locate(',3,', ','+hide_from_publishers+',') = 0
order by rank desc
You need to split the string of values into separate values. See this SO question...
Can Mysql Split a column?
As well as the supplied example...
http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
Here is another SO question:
MySQL query finding values in a comma separated string
And the suggested solution:
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set