QueryBuilder: Search a value in a column containing comma-separated integers - doctrine-orm

I have a column tags containing ids in a comma separated list.
I want to search all rows where a given value is in that column.
Say I have two rows where the column tags looks like this:
Row1: 1,2,3,4
Row2: 2,5,3,12
and I want to search for a row where the column contains a 1. I try to do it this way:
$qb = $this->createQueryBuilder('p')
->where(':value IN (p.tags))
->setParameter('value', 1);
I expect it to do something like
SELECT p.* FROM mytable AS p WHERE 1 IN (p.tags)
Executing this in MySQL directly works perfectly. In Doctrine it does not work:
Error: Expected Literal, got 'p'
It works the other way around, though, but this is not what I need:
->where("p.tags IN :value")
I've tried a lot to make this work, but it just won't... Any ideas?

I think you should use the LIKE function for each scenario, as example:
$q = "1";
$qb = $this->createQueryBuilder('p')
->andWhere(
$this->expr()->orX(
$this->expr()->like('p.tags', $this->expr()->literal($q.',%')), // Start with...
$this->expr()->like('p.tags', $this->expr()->literal('%,'.$q.',%')), // In the middle...
$this->expr()->like('p.tags', $this->expr()->literal('%,'.$q)), // End with...
),
);
See the SQL statement result in this fiddle
Hope this help

Related

How to return a value when a cell matches something without a certain set of characters? Using regexmatch

I'm using IFS and REGEXMATCH to assign values to each cell. The desired outcome is to return 'Info' if a cell contains 'how' 'where' 'what' 'who' but at the same time does not contain 'buy' 'coupon' 'discount' and 'deals'. If the cell contains 'buy' 'coupon' 'discount' and 'deals', it should return 'Commercial'.
For example: cell containing 'where to go' should be Info,
cell containing 'how to buy' should be 'Commercial' because of the 'buy' keyword
My current formula looks like this:
=IFS(REGEXMATCH(J9,"**how|where|what|who**<>buy<>coupon<>discount<>deals"),"Info",REGEXMATCH(J9,"buy|coupon|discount|deals"),"Commercial")
The problem here is it is returning 'Info' for cells like 'how to buy' when it should return 'Commercial'. It only works for 'who', but not for 'how' 'where' and 'what'.
Any thoughts what could be wrong?
I'm still new to regex, would appreciate it if anyone could help me fix this!
You can use the following formula instead
=IF(AND(REGEXMATCH(J8,"how|where|what|who"),NOT(REGEXMATCH(J8,"buy|coupon|discount|deals"))),"Info","Commercial")
You cannot use <> in a regex. We use the NOT instead.
Functions used:
REGEXMATCH
IF
AND
NOT

PowerQuery: How to replace text with each column name for multiple columns

I'm trying to replace "x" in each column (excepts for the first 2 columns) with the column name in a table with an unknown number of columns but with at least 2 columns.
I found the code to change one column, but I want it to be dynamic:
#"Ersatt värde" = Table.ReplaceValue(Källa,"x", Table.ColumnNames(Källa){2},Replacer.ReplaceText,{Table.ColumnNames(Källa){2}})
Any ideas on how to solve it?
If I understand correctly, I think you can try either approach below:
#"Ersatt värde" =
let
columnsToTransform = List.Skip(Table.ColumnNames(Källa), 2),
accumulated = List.Accumulate(columnsToTransform, Källa, (tableState as table, columnName as text) =>
Table.ReplaceValue(tableState,"x", columnName, Replacer.ReplaceText, {columnName})
)
in accumulated
or:
#"Ersatt värde" =
let
columnsToTransform = List.Skip(Table.ColumnNames(Källa), 2),
transformations = List.Transform(columnsToTransform, (columnName) => {columnName, each
Replacer.ReplaceText(Text.From(_), "x", columnName)}),
transformed = Table.TransformColumns(Källa, transformations)
in transformed,
Both ways follow a similar approach:
Figure out which columns to do replacements in (i.e. all except the first 2 columns)
Loop over columns determined in previous step and actually do the replacement.
I've used Replacer.ReplaceText since that's what you'd used in your question, but I believe this will replace both partial matches and full matches.
If you only want full matches to be replaced, I think you can use Replacer.ReplaceValue instead.

How to extract values from a text string using a number as delimiter?

I have a bit of a unique situation, I have a column of data that has text values:
Column
sdfsadf42lkjdflk
skld35kdfosdffj
kdfjsi78ldsfjoi
Result should look like:
Column
42lkjdflk
35kdfosdffj
78ldsfjoi
Is there a way to cut out everything before a number? A generalized way would be nice in the event that number currently not included can still be evaluated for (the instance of a number always being used is the only constant)
You can try finding the index and then slicing the str using the same index. I will show you with an example.
var str = "skld35kdfosdffj";
var firstDigit = str.search(/\d/);
str = str.slice(firstDigit,str.length);
console.log(str);
Assuming your column is named ColumnName, in powerquery, add custom column with formula
= Text.RemoveRange([ColumnName], 0, Text.PositionOfAny([ColumnName],{"0".."9"}))

Make new rows in Pandas dataframe based on df.str.findall matches?

I have a dataframe current_df I want to create a new row for each regex match that occurs in each entry of column_1. I currently have this below:
current_df['new_column']=current_df['column_1'].str.findall('(?<=ABC).*?(?=XYZ)')
This appends a list of the matches for the regex in each row. How do I create a new row for each match? I'm guessing something with list comprehension, but I'm not sure what it'd be exactly.
The output df would be something like:
column_1 column2 new_column
ABC_stuff_to_match_XYZ_ABC_more_stuff_to_match_XYZ... data _stuff_to_match_
ABC_stuff_to_match_XYZ_ABC_more_stuff_to_match_XYZ... data _more_stuff_to_match_
ABC_a_different_but_important_piece_of_data_XYZ_ABC_find_me_too_XYZ... different_stuff _a_different_but_important_piece_of_data_
ABC_a_different_but_important_piece_of_data_XYZ_ABC_find_me_too_XYZ... different_stuff _find_me_too_
Use can use extractall, and with merge:
df.merge(df.column_1.str.extractall('(?<=ABC)(.*?)(?=XYZ)')
.reset_index(level=-1, drop=True),
left_index=True,
right_index=True
)
Use the extract function.
df['new_column'] = df['column_1'].str.extract('(?<=ABC).*?(?=XYZ)', expand=True)

Looking for the proper way to format the text in a column and compare that with the value of a cell?

I am trying to format the information from a column that I am querying and compare that to information in a cell. I have tried to hack together various ways to do this, but I am not a proficient SQL/spreadsheet user.
In COLUMN I there is nothing.
In COLUMN K there is a match on A2.
In COLUMN N there is Information formatted like 31'-40' and 41'+.
I would prefer to use = instead of contains.
The REPLACE Function seems to work when I substitute N for a String and run it on the W3 School Website.
The REGEXREPLACE seems to work on D2. I would expect them to match, but they do not.
COUNT( QUERY( '2019'!A2:P, "select D where I='' and upper(K) contains '" & UPPER(A2) & "' and REPLACE(REPLACE(REPLACE(N, '-', ''), '''', ''), '+','') contains '"& Regexreplace(D2,"[[:punct:]]","") &"' ")
I get 0 matches.
you almost had it, but try like this:
=COUNTA(FILTER(2019!D2:D, I2:I="",
REGEXMATCH(UPPER(K2:K), UPPER(A2)),
REGEXMATCH(UPPER(N2:N), UPPER(D2))))