Phalcon use LIKE inside Query\Builder on two columns - phalcon

How can I select data from two columns using Query\Builder with 'LIKE' %something% and 'OR'.
I get no data if there is no match in column title despite the use of the OR, but there must be a match inside the column subtitle.
I'm currently doing this:
$Query->andWhere(
'MyData.title LIKE :searchValue: OR MyData.subtitle LIKE :searchValue:', [
'searchValue' => '%' . $searchValue . '%',
]
);

Well it looks fine. Are you sure there is match? Maybe check what query is produced? You can easily add logs of all queries using 'db:beforeQuery' event.
Maybe you have some other conditions?

Related

Open Refine: Exporting nested XML with templating

I have a question regarding the templating option for XML in Open Refine. Is it possible to export data from two columns in a nested XML-structure, if both columns contain multiple values, that need to be split first?
Here's an example to illustrate better what I mean. My columns look like this:
Column1
Column2
https://d-nb.info/gnd/119119110;https://d-nb.info/gnd/118529889
Grützner, Eduard von;Elisabeth II., Großbritannien, Königin
https://d-nb.info/gnd/1037554086;https://d-nb.info/gnd/1245873660
Müller, Jakob;Meier, Anina
Each value separated by semicolon in Column1 has a corresponding value in Column2 in the right order and my desired output would look like this:
<rootElement>
<recordRootElement>
...
<edm:Agent rdf:about="https://d-nb.info/gnd/119119110">
<skos:prefLabel xml:lang="zxx">Grützner, Eduard von</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/118529889">
<skos:prefLabel xml:lang="zxx">Elisabeth II., Großbritannien, Königin</skos:prefLabel>
</edm:Agent>
...
</recordRootElement>
<recordRootElement>
...
<edm:Agent rdf:about="https://d-nb.info/gnd/1037554086">
<skos:prefLabel xml:lang="zxx">Müller, Jakob</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/1245873660">
<skos:prefLabel xml:lang="zxx">Meier, Anina</skos:prefLabel>
</edm:Agent>
...
</recordRootElement>
<rootElement>
(note: in my initial posting, the position of the root element was not indicated and it looked like this:
<edm:Agent rdf:about="https://d-nb.info/gnd/119119110">
<skos:prefLabel xml:lang="zxx">Grützner, Eduard von</skos:prefLabel>
</edm:Agent>
<edm:Agent rdf:about="https://d-nb.info/gnd/118529889">
<skos:prefLabel xml:lang="zxx">Elisabeth II., Großbritannien, Königin</skos:prefLabel>
</edm:Agent>
)
I managed to split the values separated by ";" for both columns like this
{{forEach(cells["Column1"].value.split(";"),v,"<edm:Agent rdf:about=\""+v+"\">"+"\n"+"</edm:Agent>")}}
{{forEach(cells["Column2"].value.split(";"),v,"<skos:prefLabel xml:lang=\"zxx\">"+v+"</skos:prefLabel>")}}
but I can't find out how to nest the splitted skos:prefLabel into the edm:Agent element. Is that even possible? If not, I would work with seperate columns or another workaround, but I wanted to make sure, if there's a more direct way before.
Thank you!
Kristina
I am going to expand the answer from RolfBly using the Templating Exporter from OpenRefine.
I do have the following assumptions:
There is some other column left of Column1 acting as record identifying column (see first screenshot).
The columns actually have some proper names
The columns URI and Name are the only columns with multiple values. Otherwise we might produce empty XML elements with the following recipe.
We will use the information about records available via GREL to determine whether to write a <recordRootElement> or not.
Recipe:
Split first Name and then URI on the separator ";" via "Edit cells" => "Split multi-valued cells".
Go to "Export" => "Templating..."
In the prefix field use the value
<?xml version="1.0" encoding="utf-8"?>
<rootElement>
Please note that I skipped the namespace imports for edm, skos, rdf and xml.
In the row template field use the value:
{{if(row.index - row.record.fromRowIndex == 0, '<recordRootElement>', '')}}
<edm:Agent rdf:about="{{escape(cells['URI'].value, 'xml')}}">
<skos:prefLabel xml:lang="zxx">{{escape(cells['Name'].value, 'xml')}}</skos:prefLabel>
</edm:Agent>
{{if(row.index - row.record.fromRowIndex == row.record.rowCount - 1, '</recordRootElement>', '')}}
The row separator field should just contain a linebreak.
In the suffix field use the value:
</rootElement>
Disclaimer: If you're keen on using only OpenRefine, this won't be the answer you were hoping for. There may be ways in OR that I don't know of. That said, here's how I would do it.
Edit The trick is to keep URL and literal side by side on one line. b2m's answer below does just that: go from right to left splitting, not from left to right. You can then skip steps 2 and 3, to get the result in the image.
split each column into 2 columns by separator ;. You'll get 4 columns, 1 and 3 belong together, and 2 and 4 belong together. I'm assuming this will be the case consistently in your data.
export 1 and 3 to a file, and export 2 and 4 to another file, of any convenient format, using the custom tabular exporter.
concatenate those two files into one single file using an editor (I use Notepad++), or any other method you may prefer. Several ways to Rome here. Result in OR would be something like this.
You then have all sorts of options to put text strings in front, between and after your two columns.
In OR, you could use transform on column URL to build your XML using the below code
(note the \n for newline, that's probably just a line feed, you may want to use \r\n for carriage return + line feed if you're using Windows).
'<edm:Agent rdf:about="' + value + '">\n<skos:prefLabel xml:lang="zxx">' + cells.Name.value + '</skos:prefLabel>\n</edm:Agent>'
to get your XML in one column, like so
which you can then export using the custom tabular exporter again. Or instead you could use Add column based on this column in a similar manner, if you want to retain your URL column.
You could even do this in the editor without re-importing the file back into OR, but that's beyond the scope of this answer.

Querying full and sub-strings via multi-valued parameter using SQL

I am building a report with Microsoft SSRS (2012) having a multi-value parameter #parCode for the user to filter for certain codes. This works perfectly fine. Generally, my query looks like this:
SELECT ...
FROM ...
WHERE
TblCode.Code IN (#Code)
ORDER BY...
The codes are of following type (just an excerpt):
C73.0
C73.1
...
C79.0
C79.1
C79.2
Now, in additon to filtering for multiple of these codes I would like to als be able to filter for sub-strings of the codes. Meaning, when the user enters (Example 1)
C79
for #parCodes The output should be
C79.0
C79.1
C79.2
So eventually the user should be able to enter (Example 2)
C73.0
C79
for #parCodes and the output would be
C73.0
C79.0
C79.1
C79.2
I managed to implement both functionalities seperately, so either filtering for multiple "complete" codes or filterting for sub-string of code, but not both simultaneously.
I tried to do something like
...
WHERE
TblCode.Code IN (#parCode +'%')
ORDER BY...
but this screws up the Example 2. On the other hand, if I try to work with LIKE or = instead of IN statement, then I won't be able to make the parameter multi-valued.
Does anyone have an idea how to realize such functionality or whether IN statement pared with multi-valued parameters simply doesn't allow for it?
Thank you very much!
Assuming you are using SQL server
WHERE (
TblCode.Code IN (#parCode)
OR
CASE
WHEN CHARINDEX('.', Code)>0 THEN LEFT(TblCode.Code, CHARINDEX('.', TblCode.Code)-1)
ELSE TblCode.Code
END IN (#parCode)
)
The first clause makes exact match so for your example matches C73.0
The second clause matches characters before the dot character so it would get values C79.0, C79.1, C79.2 etc
Warning: Filtering using expressions would invalidate the use of an index on TblCode.Code

How can I write a WHERE statement that looks for a variable OR Null?

I am attempting to write a query for an Altiris report. This query is looking for machine information. The query works fine, however the problem I am running into is with my parameters. I have set up multiple parameters within Altiris to allow me to filter and search through the report for multiple fields. Then, in my query, I add those parameters into the WHERE statements.
All of the parameters were working fine, until I added Make and Model parameters. We have quite a few machines that do not have information populated into these fields. So when I add in the WHERE xxxx LIKE N'%Make%', I lose about 500 machines based on it now only looking for machines with something in that field. I tried to fix this by adding lines like the following:
Where ((xxxx LIKE N'%Make%' OR xxxx is null))
This kind of worked, in that now the report shows all machines... But if I enter "HP" into the Make parameter field and then rerun the report... it shows all HP machines like I want, but also all of the null machines as well.
How can I rewrite my where statements so that they do not exclude machines in the report, and allow me to filter by all HP machines, without showing null values as well?
Hope this made sense, and thank you
In this snip of code, the last two lines make me lose about 500 machines in my total machine count of the report. It is omitting all machines that have null values.
WHERE
(dbo.OS_Version.[OS Name] LIKE N'%OSName%') AND
(dbo.OS_Version.[OS Version] LIKE N'%Build%') AND
(dbo.OS_Version.Name LIKE N'%Name%') AND
(dbo.Inv_AeX_AC_Identification.[Hardware Serial Number] LIKE N'%Serial%') AND
(dbo.vHWComputerSystem.Manufacturer LIKE N'%Make%') AND
(dbo.vHWComputerSystem.Model LIKE N'%Model%')
This is how I tried to fix it, and now I get all 20,000 machines. But my make/model fields report on null fields as well.
WHERE
(dbo.OS_Version.[OS Name] LIKE N'%OSName%') AND
(dbo.OS_Version.[OS Version] LIKE N'%Build%') AND
(dbo.OS_Version.Name LIKE N'%Name%') AND
(dbo.Inv_AeX_AC_Identification.[Hardware Serial Number] LIKE N'%Serial%') AND
((dbo.vHWComputerSystem.Manufacturer LIKE N'%Make%') OR (dbo.vHWComputerSystem.Manufacturer is null)) AND
((dbo.vHWComputerSystem.Model LIKE N'%Model%') OR (dbo.vHWComputerSystem.Model is null))
I'm guess that if you don't enter a value for a parameter, it's coming through as an empty string, and of course, every varchar is LIKE '%%'.
I'm not sure what RDBMS this is, but if the ISNULL function is available, try this:
where ((ISNULL(xxxx,'') LIKE N'%Make%')
This replaces nulls with the empty string before doing the LIKE comparison.
I think you want something like this:
(cs.Manufacturer LIKE N'%#Make%' OR #Make = '') AND
(cs.Model LIKE N'%#Model%' OR #Model = '')
I am using = '' rather than IS NULL because you are clearly not passing in the parameters as NULL values (the LIKE wouldn't work).
This does not provide a method for filtering to get only the NULL values, because you are using the "special value" for the parameter to mean "don't apply a filter here".
Note that cs is intended as a table alias. I also strongly recommend that you use table aliases so your queries are easier to write and to read.
I think you're looking for something like WHERE ISNULL(Model, '') LIKE '%Model%'. However, you should replace '%Model%' with a variable. The above example would literally match the word 'Model'
DECLARE #Model NVARCHAR(100) = 'T-800'
...
WHERE ISNULL(Model, '') LIKE '%' + #Model + '%'
^ This would not include rows with NULL Model values

Grails withCriteria, value between two database columns?

how do I test if a value is between two of my database columns?
I need to do something like this:
between(column1, column2, 'value')
or something like this:
or{
and {
ge("hora_inicio", evento.hora_inicio)
le("hora_fim", evento.hora_inicio)
}
and {
ge("hora_inicio", evento.hora_fim)
le("hora_fim", evento.hora_fim)
}
}
any ideias?
Thanks!
There is not an option to check that two columns are between a value. You are going to have to do two separate comparisons. You can compare one database column to another though, but it doesn't see like that's quite what you want. See documentation on this here: http://docs.grails.org/latest/ref/Domain%20Classes/createCriteria.html
From your second example, it looks like you need to find all the entries that have a start time between evento.hora_inicio and evento.hora_fim or that have a order time between evento.hora_inicio and evento.hora_fim.
It feels like this can be simplified to look for all the entries that have an hora_inicio before the evento.hora_fim and have a hora_fim after the evento.hora_inicio. That would look something like this:
Event evento = getEventFromSomewhere()
Appointment.createCriteria().list{
le 'hora_inicio', evento.hora_fim
ge 'hora_fim', evento.hora_inicio
}

Mixing 'Like' with comparators in an iif statement?

I'm attempting to use the query builder to formulate a query based on user input on a form, but I'm running into an issue.
I've been using this code to filter and check for null/"ALL" field before which is working fine.
Like IIf([Forms]![TransactionsForm]![ComboActStatus]="ALL","*",
[Forms]![TransactionsForm]![ComboActStatus])
But I run into an issue when I want to do the same thing with fields that signify a range. I attempted this:
IIf([forms]![TransactionsForm]![txtAmountFrom] Is Null Or
[forms]![TransactionsForm]![txtAmountTo] Is Null,
([dbo_customerQuery].[amount]) Like "*",
([dbo_customerQuery].[amount])>=[forms]! [TransactionsForm]![txtAmountFrom] And
([dbo_customerQuery].[amount])<=[Forms]![TransactionsForm]![txtAmountTo])
But it's causing my entire query to fail. How can I do this similar thing? Use "Like *" in the null case (return everything), but use comparators rather than "like" statements in the second case?
Unless I'm missing something LIKE "*" will return true for all values, so this should work:
IIf([forms]![TransactionsForm]![txtAmountFrom] Is Null Or
[forms]![TransactionsForm]![txtAmountTo] Is Null,
true,
([dbo_customerQuery].[amount])>=[forms]! [TransactionsForm]![txtAmountFrom] And
[dbo_customerQuery].[amount])<=[Forms]![TransactionsForm]![txtAmountTo])
)
The code that finally worked for me, and didn't have Access split it into separate lines was:
>=IIf([forms]![TransactionsForm]![txtAmountFrom] Is Null,0,[forms]![TransactionsForm]!
[txtAmountFrom]) And <=IIf([forms]![TransactionsForm]![txtAmountTo] Is Null,9999999999,
[forms]![TransactionsForm]![txtAmountTo])