SQL Use Greater/Less Than with like and wildcards - sql

I'm currently a bit stumped on how to implement a certain thing. Basically I have an embedded database(which really hates JOINs, performance-wise) and the requirement of adding a wildcard mechanism to a search field. Currently the search field allows the User to input a date and some amounts/revenues which is matched using something like:
SELECT * FROM table where date >= '{0}' AND date <= '{1}'
EDIT: This is due to the fact that a .NET adapter generates the SQL at runtime with various combinations of AND-clauses being possible. Could be the user inputs only a value for {0}, could be he only inputs one for {1}, could be he inputs both, could be he inputs none. Therefore BETWEEN sadly would fall flat unless I start some serious regexing.
I would like to use the keyword LIKE to implement something like:
SELECT * FROM table where date >= LIKE '{0}' AND date <= LIKE '{1}'
with {0} being something like "2015.01*"
I recognize that Date might be a bit much, but using stuff like amounts or revenues is this possible? If so, what's the right syntax? Google is not my friend on this...
Thanks for all your help in advance!

LIKE is doing a regular expression matching, so for example LIKE '%a' matches '1a', but also '2a'. From this it is quite clear that a >= LIKE '...' is not possible.
What you could do is build a string from the date, so that you have for example 'YYYYMMDD', then you could easily compare with LIKE 'YYYYMM%' or with >= 'YYYYMM'.
Still I do not understand why you don't just use the SELECT * FROM table where date >= '{0}' AND date <= '{1}' (or a variant of that query using between) that you already proposed.

Related

How to display output with a % sign. eg: 90%

the below query gives me result as 90 AND NOT 90%.
SELECT
CAST(convert(decimal(20,10),[Total]) as int) AS 'TT'
,cast((convert(decimal(20,10),([Count_Checked_Out]/convert(decimal(20,10),[Total])))* 100) as int) AS '%_Checked_Out'
If you want formatting, of any kind, you must convert the value from a number type, like int, to a string type, like nvarchar. Exactly what this looks like depends on what specific database platform you're using.
But in most cases, you're better off leaving this work for your client code or reporting tool.
If you want to do this in sql query you can do something like this
select concat(90,"%") as percent_value;
But as #Joel Coehoom pointed out you should do this in your presentation layer
http://sqlfiddle.com/#!9/9eecb/191808/0

DB2 Get value based on 5 character of field

I am working with a pretty badly designed table. I have a field called optional fields which for some reason has been used as a catch-all for someone who didn't want to create the table correctly.
I need to make a query where I look at this optional_fields value and do a comparison on the fifth value of the string in optional_fields.
The value from this field is something like NN14YN...N
My query would be something like:
SELECT COMPANY_NUMBER
FROM table
WHERE fifth character of OPtional Fields = 'Y'
Looking at the supported string functions in DB2 (according to the documentation for DB2 for Linux UNIX and Windows 9.7.0) it would seem that substr could be used:
SELECT COMPANY_NUMBER
FROM table
WHERE substr(optional_Fields,5,1) = 'Y'
In addition to the great answer from #jpw, if you for some reason need to check multiple positions within the string (which I have unfortunately had to do at one time), you can use an IN, and invert the "normal" order, like so:
...
WHERE 'Y' in (
substr(t.flags_field, 123, 1)
,substr(t.flags_field, 19, 1)
,substr(t.flags_field, 128, 1)
,substr(t.flags_field, 1, 1)
)
Just thought I would share. It surprised me the first time I used it!

Pentaho Dynamic SQL queries

I have a Pentaho CDE project in development and i wanted to display a chart wich depends on several parameters (like month, year, precise date, country, etc). But when i want to "add" another parameter to my query, it doesn't work anymore... So i'm sure i'm doing something wrong but what ? Please take a look for the parameter month for example :
Select_months_query : (this is for my checkbox)
SELECT
"All" AS MONTH(TransactionDate)
UNION
SELECT DISTINCT MONTH(TransactionDate) FROM order ORDER BY MONTH(TransactionDate);
Select_barchart_query : (this is for my chart, don't mind the other tables)
SELECT pginit.Family, SUM(order.AmountEUR) AS SALES
FROM pginit INNER JOIN statg ON pginit.PG = statg.PGInit INNER JOIN order ON statg.StatGroup = order.StatGroup
WHERE (MONTH(order.TransactionDate) IN (${month}) OR "All" IN (${month}) OR ${month} IS NULL) AND
/*/* Apply the same pattern for another parameter (like year for example) *\*\
GROUP BY pginit.Family
ORDER BY SALES;
(Here, ${month} is a parameter in CDE)
Any ideas on how to do it ?
I read something there that said to use CASE clauses... But how ?
http://forums.pentaho.com/showthread.php?136969-Parametrized-SQL-clause-in-CDE&highlight=dynamic
Thank you for your help !
Try simplifying that query until it runs and returns something and work from there.
Here are some things I would look into as possible causes:
I think you need single quotes around ${parameter} expressions if they're strings;
"All" should probably be 'All' (single quotes instead of double quotes);
Avoid multi-line comments. I don't think you can have multi-line comments in CDE SQL queries, although -- for single line comments usually works.
Be careful with multi-valued parameters; they are passed as arrays, which CDA will convert into comma separated lists. Try with a single valued parameter, using = instead of IN.

How to write SQL query with many % wildcard characters

I have a coloumn in Sql Server table as:
companystring = {"CompanyId":0,"CompanyType":1,"CompanyName":"Test
215","TradingName":"Test 215","RegistrationNumber":"Test
215","Email":"test215#tradeslot.com","Website":"Test
215","DateStarted":"2012","CompanyValidationErrors":[],"CompanyCode":null}
I want to query the column to search for
companyname like '%CompanyName":"%test 2%","%'
I want to know if I'm querying correctly, because for some search string it does not yield the proper result. Could anyone please help me with this?
Edit: I have removed the format bold
% is a special character that means a wildcard. If you want to find the actual character inside a string, you need to escape it.
DECLARE #d TABLE(id INT, s VARCHAR(32));
INSERT #d VALUES(1,'foo%bar'),(2,'fooblat');
SELECT id, s FROM #d WHERE s LIKE 'foo[%]%'; -- returns only 1
SELECT id, s FROM #d WHERE s LIKE 'foo%'; -- returns both 1 and 2
Depending on your platform, you might be able to use some combination of regular expressions and/or lambda expressions which are built into its main libraries. For example, .NET has LINQ , which is a powerful tool that abstracts querying and which provides leveraging for searches.
It looks like you have JSON data stored in a column called "companystring". If you want to search within the JSON data from SQL things get very tricky.
I would suggest you look at doing some extra processing at insert/update to expose the properties of the JSON you want to search on.
If you search in the way you describe, you would actually need to use Regular Expressions or something else to make it reliable.
In your example you say you want to search for:
companystring like '%CompanyName":"%test 2%","%'
I understand this as searching inside the JSON for the string "test 2" somewhere inside the "CompanyName" property. Unfortunately this would also return results where "test 2" was found in any other property after "CompanyName", such as the following:
-- formatted for readability
companystring = '{
"CompanyId":0,
"CompanyType":1,
"CompanyName":"Test Something 215",
"TradingName":"Test 215",
"RegistrationNumber":"Test 215",
"Email":"test215#tradeslot.com",
"Website":"Test 215",
"DateStarted":"2012",
"CompanyValidationErrors":[],
"CompanyCode":null}'
Even though "test 2" isn't in the CompanyName, it is in the text following it (TradingName), which is also followed by the string "," so it would meet your search criteria.
Another option would be to create a view that exposes the value of CompanyName using a column defined as follows:
LEFT(
SUBSTRING(companystring, CHARINDEX('"CompanyName":"', companystring) + LEN('"CompanyName":"'), LEN(companystring)),
CHARINDEX('"', SUBSTRING(companystring, CHARINDEX('"CompanyName":"', companystring) + LEN('"CompanyName":"'), LEN(companystring))) - 1
) AS CompanyName
Then you could query that view using WHERE CompanyName LIKE '%test 2%' and it would work, although performance could be an issue.
The logic of the above is to get everything after "CompanyName":":
SUBSTRING(companystring, CHARINDEX('"CompanyName":"', companystring) + LEN('"CompanyName":"'), LEN(companystring))
Up to but not including the first " in the sub-string (which is why it is used twice).

Microsoft Access SQL Date Comparison

I am using Access 2007.
I need to return rows with a date/time field falling within a date range to be specified in query parameters.
The following doesn't error out, but doesn't appear to work.
SELECT FIELDS FROM FOO
WHERE (FOO.CREATED_DTG BETWEEN [START_DTG] And [END_DTG]);
Likewise this doesn't work for me
SELECT FIELDS FROM FOO
WHERE (FOO.CREATED_DTG >= [START_DTG] And FOO.CREATED_DTG < [END_DTG]);
How can I get this to work?
Update: Using CDate doesn't seem to make a difference.
Is BLAH the name of a field or a table? As you SELECT BLAH I imagine it names a field, but then BLAH.CREATED_DTG makes no sense -- do you mean FOO.CREATED_DTG perchance?
Does your dates start and end with a #?
also you have <= and >= ... you probably only want = on one of these operators.
Are you sure the CREATED_DTG field is Date format?
Have you tried
WHERE (FOO.CREATED_DTG BETWEEN #01/01/1971# And #07/07/2009#);
(or whatever is appropriate in the way of dates -- the point is, not a parameter query)
Are [START____DTG] and [END____DTG] fields in the table FOO, or are they parameters? If they are parameters, then you need to declare their type in order to get validation of the input values. If so, you should add this before the first line of your SELECT statement:
PARAMETERS [START_DTG] DateTime, [END_DTG] DateTime;