after searching through the whole www I finally ended up here with a question and hopefully more capable responders than I am.
I am trying to implement a full text search on my webpage.
The Sql query works with one WHERE condition but not with several. Unfortunately I have no clue how to solve my problem with the help of EXIST / IN / INNER JOIN or other Operators.
Code which works:
$sql = "SELECT * FROM artikel WHERE author LIKE '$suchtext' LIMIT $offset, $no_of_abs";
Code which doesnt work:
$sql = "SELECT * FROM artikel WHERE (author OR shorty OR vollartikel) LIKE '%$suchtext%' LIMIT $offset, $no_of_abs";
The variable $suchtext is correctly passed and received through jquery $ajax POST and my php script.
Example goal:
author | volltext | shorty
--------+-------------+---------
tulum | tul | asf
rae | zutotu | vizetu
$suchtext is "tu"
Results: 2
Row1 & Row2
I appreciate any answers.
Solution:
$sql = "SELECT * FROM artikel WHERE author LIKE '%$suchtext%' OR shorty LIKE '%$suchtext%' OR vollartikel LIKE '%$suchtext%' LIMIT $offset, $no_of_abs";
LIKE is a binary operator that takes two strings. OR is a boolean operator that operates on boolean values.
You need to explicitly list this out:
(author LIKE ? OR
shorty LIKE ? OR
vollartikel LIKE ?
)
Note that this uses ? as a parameter placeholder. Use parameters when constructing SQL queries in applications.
Related
I have several OR in my SQL statement so I want to save a chuck of it in a cfsavecontent. Here is that part:
<cfsavecontent variable="checkDepartment">
<cfif #wrkDept# EQ #dept[2][1]#>
Department = 'Health' AND
<cfelse>
Department = '#wrkDept#' AND
</cfif>
</cfsavecontent>
But the error I get on the page shows 2 sets of apostrophes around the word Health.
SQL
SELECT COUNT(*) AS numItems
FROM IT_PROJECTS
WHERE
Department = ''Health'' AND
status = 'Cancelled'
Can anyone help me to only get a single apostrophe? Thanks
So this answer seems a lot more complicated than it really is. And without knowing specifically what your query looks like (re:OR conditions), I'm not really sure how to structure it. It can be better. The goal should be to make one single trip to your SQL server with the query that makes the most sense for the data you're trying to get. I'm not sure what you are trying to do with cfsavecontent, but I don't think you need it.
The bulk of my example query (https://trycf.com/gist/4e1f46bfa84a6748aced0f9ee8221c6d/acf2016?theme=monokai) is setup. I chose to go with a cfscript format, because as Redtopia said, I also find it much easier to build a dynamic query in cfscript.
After initial setup, I basically just script out the variables I'll use in my final queryExecute().
// Base query.
qry = "SELECT count(*) AS theCount FROM IT_PROJECTS WHERE 1=1 " ;
// This is our dynamic filter that we build below.
qfilter = {} ;
// Query options.
opts = { "dbtype":"query" } ;
After we have our base, I build up the dynamic part of the query. This is the part that will likely change quite a bit depending on your current needs and setup.
For the first part, I basically replaced your cfif with a ternary evaluation. I'm not sure how your data plays into the evaluation of dept or where that array comes from. But from there I build a basic included statement of the query and set up the queryparam values for it. Then I add a second check that will pick a different set of values for the query (currently based on even/odd seconds). Again, I'm not sure of the intent of your query here, so I just made something dynamic.
//////////// BUILD DYNAMIC FILTER ////////////
qdept = ( wrkDept == dept[2][1] ) ? 'Health' : wrkDept ;
/// This one is an included filter:
qry &= " AND department = :dpt AND status = :sts " ;
qfilter.dpt = {"value":qdept,"cfsqltype":"CFSQLVARCHAR"} ;
qfilter.sts = {"value":"Cancelled","cfsqltype":"CFSQLVARCHAR"} ;
/// Adding Dynamic ORs
// Dynamically set status based on even/odd seconds.
qStatus = ( now().second()%2==0) ? "Cancelled" : "Active" ;
qry &= " OR ( department = :dpt2 AND status = :sts2 ) " ;
qfilter.dpt2 = {value:"IT",cfsqltype:"CFSQLVARCHAR"} ;
qfilter.sts2 = {value:qStatus,cfsqltype:"CFSQLVARCHAR"} ;
This gives us a SQL string that looks like:
SELECT count(*) AS theCount
FROM IT_PROJECTS
WHERE 1=1
AND department = :dpt AND status = :sts
OR
( department = :dpt2 AND status = :sts2 )
With a SQL statement, the placement of AND and OR conditions can greatly impact the results. Use parenthesis to group conditions how you need them.
After we've built the query string, we just have to plug it and our queryparams into the queryExecute().
result = queryExecute( qry , qfilter , opts ) ;
And if we want to output our data, we can go:
writeOutput("There are " & result.theCount & " records." ) ;
Which gives us:
There are 8 records.
Again, I don't know what your main conditions look like. If you can give me an example of a query with a bunch of ORs and ANDs, I'll try to modify this for you.
Apologies for posting a new question but I just can't think how to search for this question.
I'm creating a Crystal Report with multiple parameters and at the moment each one is connected by an ‘AND’ in the Report > Selection Formulas part of the report (not the SQL command part).
I haven’t fully authored the report and it contains lots of arrays to deal with multiple text values and wildcard searches but I think my question should be more around logic than the technical functions.
So…
Parameters are for things like product code, date range, country, batch number etc.
Currently the parameters I’m concerned with are Faults and keyword searches for complaints against products.
(Query 1) If all other parameters are set to default I can enter Fault Combination = ‘Assembly – Code’ and that gives me 17 records.
(Query 2) Entering keyword = ‘%unit%’ gives me 55 records.
The 2 parameters are connected by an AND so if I use Fault Combination = ‘Assembly – Code’ and Keyword = ‘%unit%’ then I get 12 records. If the connect the 2 queries with OR then I get 12 records.
If I compare the unique records, in excel, between query 1 & 2 then there are 60 records with Fault Combination = ‘Assembly – Code’ OR keyword = ‘%unit%.
How can write the parameter formula to get the 60 unique records with one query?
Many thanks!
Gareth
Edit - Code Added
This is the segment i'm concerned with. The arrays are defined earlier in the statement and the '*' & '%' parts of the query below are just to deal with the different wildcard operators between SQL and Crystal. There are a lot of other parameters but these 3 are the only ones that need the OR kind or connection.
Hope that helps!
(IF "%" LIKE array_fn2
THEN ((ISNULL({Command.FaultNoun})=TRUE) OR ({Command.FaultNoun} LIKE '*'))
ELSE IF {Command.RecordType} = 'Complaint'
THEN ({Command.FaultNoun} like array_fn2)
ELSE ((ISNULL({Command.FaultNoun})=TRUE) OR ({Command.FaultNoun} LIKE '*'))) AND
(IF "%" LIKE array_fa2
THEN ((ISNULL({Command.FaultAdjective})=TRUE) OR ({Command.FaultAdjective} LIKE '*'))
ELSE IF {Command.RecordType} = 'Complaint'
THEN ({Command.FaultAdjective} like array_fa2)
ELSE ((ISNULL({Command.FaultAdjective})=TRUE) OR ({Command.FaultAdjective} LIKE '*'))) AND
(IF ("%" LIKE array_k2) OR ({Command.RecordType} = 'Sale')
THEN ((ISNULL({Command.ActualStatements})=TRUE) OR ({Command.ActualStatements} LIKE '*')
OR (ISNULL({Command.ResultsAnalysis})=TRUE) OR ({Command.ResultsAnalysis} LIKE '*')
OR (ISNULL({Command.Observation})= TRUE) OR ({Command.Observation} LIKE '*'))
ELSE
({Command.ActualStatements} like array_k2) OR
({Command.ResultsAnalysis} like array_k2) OR
({Command.Observation} like array_k2))
According to documentation here, I should be able to reference a table wildcard function as an alias:
...
FROM
[project_name:]datasetId.tableId |
(subselect_clause) |
table wildcard function
[[AS] alias]
...
But, when I try to do this, things fail:
bq query "SELECT * FROM TABLE_QUERY(my_data, \"TIMESTAMP(table_id) BETWEEN TIMESTAMP('2014-05-21') AND TIMESTAMP('2014-06-10')\") AS blah WHERE blah.foo = 5 LIMIT 30"
Waiting on bqjob_some_id ... (0s) Current status: DONE
BigQuery error in query operation: Error processing job 'some_id': Field 'blah.foo' not found in table 'mydata.20140521'; did you mean 'foo2'?
I want to do a join on the data returned from the wildcard function treating it as a single table, so aliasing it is very important to me. Ideas?
The page you linked to does mention "Do not use alias with a table wildcard function."
You might want to try
SELECT *
FROM (SELECT * FROM TABLE_QUERY(--insert query here--)) AS blah
WHERE blah.foo = 5 LIMIT 30"
I'm trying to query the Oracle v$session table using Groovy (imported groovy.sql.SQL) like this:
sql.eachRow("""
Select
'Y' as runInd
from v$session
where upper(module) = ?
having count(*) > 1
""", [programName]) {row -> etc...}
But Groovy keeps telling me: "Groovy:Apparent variable 'session' was found in a static scope but doesn't refer to a local variable, static field or class."
It apparently doesn't like the table called v$session. I've tried many things, I'm not sure why I can't find out how to do this. Any help is appreciated. Thanks!
Tom
Instead of """ which marks it as a multi-line templated groovy string, try ''' which shouldn't try to template things following a $:
sql.eachRow( '''Select
| 'Y' as runInd
| from v$session
| where upper(module) = ?
| having count(*) > 1'''.stripMargin(), [programName]) { row ->
etc...
}
My final goal is I want to get plid and portletId that can be display my article(or entry with any type if it is possible).
I have sql query that return me any portlet availble for display my article.
But when I have to use dynamicQuery to get the same results, I get problem with xPath and array comparison, please help!
SELECT * FROM portletpreferences pr
WHERE pr.preferences != '<portlet-preferences />' AND pr.ownerid = 0 AND pr.portletid ilike '%_INSTANCE_%' AND pr.plid IN(
SELECT layout.plid FROM layout
WHERE layout.type_ = 'portlet' AND layout.groupid = 19 AND layout.hidden_ is false)
AND pr.portletpreferencesid IN (
SELECT pr.portletpreferencesid FROM portletpreferences pr
WHERE 'true' = ANY(xpath('//preference[name="anyAssetType"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[])
OR (SELECT (array(SELECT id_ FROM journalstructure))::text[]) && xpath('//preference[name="classTypeIds"]/value/text()', XMLPARSE(DOCUMENT pr.preferences))::text[] )
If you are bent upon using this same query, then use this query directly with Custom-SQL in liferay by creating custom-finders instead of using DynamicQuery. That would give you a lot of flexibility in using any type of SQL query directly.
I don't think this query can be converted to DynamicQuery, but if you do manage to convert it then please do post it here :-)
DynamicQuery is very powerful, see e.g. my answer how to find layouts with specific JournalArticles. I think your requirement is similar to this one:
Liferay: How to find all Layouts with the specific JournalArticle in AssetPublisher portlets?