Sphinx - MySQL query between/larger than - mysql

I have Sphinx running to index my MySQL query's.
When I do the following SQL query I get a perfect result:
SELECT * FROM huisjesIndex WHERE MATCH('#formatted "^20120901$"') ORDER BY huis_contract DESC, global_points DESC LIMIT 200,20;
But I would like to replace MATCH('#formatted "^20120901$"') with a larger/smaller than query. In SQL I would do the following: formatted BETWEEN 20120901 AND 20120931. Unfortunately this draws an error on Sphinx.
Can anyone give me the syntax of the SQL query to do a query on a range? I need this to get results for the entire 201209 month.
EDIT
I was able to answer my own question.
When using MATCH() the value described has to be a field (because you are string searching).
When you do a compare like 'int >= 0' then the int must be an attribute.
Thanks for suggestions!

Related

Wrong results in Laravel eloquent query using date filter

I have to extract results from DB having date column bigger than today (basically i need to see the up coming events).
In real world I play in my MySql console:
select * from searcheable where MATCH (title,description) AGAINST ('rock' IN BOOLEAN MODE) and date > CURDATE() order by date asc
And it works well.
I'm trying to extract same data in eloquent style using Laravel, and I wrote:
$results = Search::search($key)
->whereDate("date",">",' CURDATE()')
->orderBy("date",'asc')
->paginate();
But it returns wrong results having wrong date.
Note the search metohd I used is for a fulltext. I don't think it's the issue.
If I do a debug and I print the sql using dd($results) it return:
select * from `searcheable` where MATCH (title,description) AGAINST (? IN BOOLEAN MODE) and date(`date`) > ? order by `date` asc
which is very similar to the starting query I'm working on.
What's wrong in my eloquent query?
Thanks for your time :)
try like this
->whereDate("date",">", now());
now() will return a Carbon DateTime instance, Which will be automatically casted to appropriate format
As it looks probably your error is in the CURDATE() format, you need to be sure both dates are in the same format, for the currentdate I always use $currentdate = Carbon::now();
then use this date for your search...

How to find rows in SQL that end with the same string?

I have a question similar to the one found here: How to find rows in SQL that start with the same string (similar rows)?, and this solution works in MySQL 5.6 but not 5.7.
I have a database (t) with multiple columns, the important ones being id and filepath, and what I am trying to accomplish is retrieving all the file paths which have the same last 5 characters. The following works in MySQL5.6, and the second SELECT works fine in 5.7:
SELECT id, filepath FROM t
WHERE SUBSTRING(filepath, -5) IN
(
SELECT SUBSTRING(filepath, -5)
FROM t
GROUP BY SUBSTRING(filepath, -5)
HAVING COUNT(*) > 1
)
But when I try to run it on 5.7 I get the error
Expression #1 of HAVING clause is not in GROUP BY clause and contains
nonaggregated column 't.filepath' which is not functionally dependent on
columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by
Sample data:
id filepath
1 /Desktop/file1.txt
2 /Desktop/file2.txt
3 /Desktop/file1.txt
and I would want to return the rows with id 1 and 3. How can I fix this for MySQL5.7?
EDIT: Also can anybody point me in the right direction for the SQL to remove the duplicates? So I would want to remove the entry for id 3 but keep the entry for id 1 and 2.
Please read the mysql documentation on the subject GROUP BY and sql_mode only_full_group_by (like your error message says):
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
I think changing the inner query to this might fix the problem:
SELECT SUBSTRING(filepath, -5) AS fpath
FROM t
GROUP BY fpath
HAVING COUNT(fpath) > 1
Edit:
As to your question of why adding the "AS fpath" works:
Adding the alias "fpath" is just a clean way to do this. The point of ONLY_FULL_GROUP_BY is that each field you use in the SELECT, HAVING, or ORDER BY must also be in the GROUP BY.
So I added the fpath-alias for multiple reasons:
For performance: The query you wrote had SUBSTRING(filepath, -5) twice, which
is bad for performance. Mysql has to execute that SUBSTRING call twice,
while in my case it has to do it only once (per row).
To fix the group-by issue: You had COUNT() in the having, but "" was not in your GROUP BY statement (I'm not even sure whether that would be possible). You had to count "something", so since "fpath" was in your SELECT and in your GROUP BY, using that as your COUNT() would fix the problem.
I prefer not to put subqueries in an IN() predicate because MySQL tends to run the subquery many times.
You can write the query differently to put the subquery in the FROM clause as a derived table. That will make MySQL run the subquery just once.
SELECT id, filepath
FROM (
SELECT SUBSTRING(filepath, -5) AS suffix, COUNT(*) AS count
FROM t
GROUP BY suffix
HAVING count > 1
) AS t1
JOIN t AS t2 ON SUBSTRING(t2.filepath, -5) = t1.suffix
This is bound to do a table-scan though, so it's going to be a costly query. It can't use an index when doing a substring comparison like that.
To optimize this, you might create a virtual column with an index.
ALTER TABLE t
ADD COLUMN filepath_last VARCHAR(10) AS (SUBSTRING_INDEX(filepath, '/', -1)),
ADD KEY (filepath_last);
Then you can query it like this, and at least the subquery uses an index:
SELECT id, filepath
FROM (
SELECT filepath_last, COUNT(*) AS count
FROM t
GROUP BY filepath_last
HAVING count > 1
) AS t1
STRAIGHT_JOIN t AS t2 ON t2.filepath_last = t1.filepath_last
The solution that ended up working for me was found here: Disable ONLY_FULL_GROUP_BY
I ran SELECT ##sql_mode then SET ##sql_mode = followed by a string containing all the values returned by the first query except for only_full_group_by, but I'm still interested in how this is to be accomplished without changing the SQL settings.

sqlsrv find maximum from the table

Previously I was using the MySQL. With that I was able to use the query below to get the maximum number from the database.
Here 'No' is the varchar(10):
SELECT max(cast(No as unsigned)) as No FROM `tableName` LIMIT 1
The above query working fine in MySQL. I want to do the same thing in the MS SQL. When I run the same query, I get the following error:
Warning: sqlsrv_fetch_array() expects parameter 1 to be resource, boolean given
Any advice on this?
There is no LIMIT in SQL Server, no unsigned datatype, and no need to quote the table name.
Does this work:
SELECT max(cast(No as bigint)) as No FROM tableName

converting mysql query to hibernate hql

There is an Issue while i try to auto Increment alphanumeric Id (or number Series) for example
in Mysql "Sample" Table 'RefNo' column (of type Varchar)
AB7
AB10
AB9
AB8
above i have four entries now i want to retrieve max (or highest value).
for this i have tried query as = SELECT MAX(RefNo) FROM sample;
but this gives result as 'AB9' which is wrong and it is supposed to return 'AB10' as result.
To get this in Mysql i have modified the Query as
= SELECT MAX(CONVERT(SUBSTRING_INDEX(RefNo,'B',-1),UNSIGNED INTEGER)) from sample where RefNo like 'AB%'
this work's fine in mysql but in hibernate (hql) query is not supported.
I hope you understand the scenerio and Please help me to solve the issue.
You should be able to use substring and cast to get the numeric part of the string and cast it to a number. Something like that (not tested) :
select max(cast(substring(sample.refNo, 3) as INTEGER)) from Sample sample ...

MySQL Is doing subquery after LIMIT syntax possible? If not, why?

I have MySQL Server version 5.1.53. I was looking for an hour to answer this question by myself. Including read the documentation itself at http://dev.mysql.com/doc/refman/5.1/en/select.html
Currently, I run this query.
SELECT dv2.timestamp
FROM data_val AS dv2
WHERE dv2.timestamp > '2011-06-10 22:26:25' ORDER BY dv3.timestamp DESC
LIMIT 1
Then I was trying to eliminate the ORDER BY syntax by determining the calculation of MAX_QUERIES minus 1. By doing that I could write,
SELECT (COUNT(*)-1) total
FROM data_val AS dv2a
WHERE dv2a.timestamp > '2011-06-10 22:26:13'
Finally the query becomes,
SELECT dv2.timestamp
FROM data_val AS dv2
WHERE dv2.timestamp > '2011-06-10 22:26:13'
LIMIT (
SELECT (COUNT(*)-1) total
FROM data_val AS dv2a
WHERE dv2a.timestamp > '2011-06-10 22:26:13'
), 1
And the error is:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( SELECT (COUNT(*)-1) total FROM data_val AS dv2a ' at line 4
I also tried to put the subquery after OFFSET syntax. but still error.
Do you have any idea why my sub-query doesn't work?
I need technical details with short,
simple, and clean explanation.
From the MySQL manual: http://dev.mysql.com/doc/refman/5.5/en/select.html
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants, with these exceptions:
Within prepared statements, LIMIT parameters can be specified using ? placeholder markers.
Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables as of MySQL 5.5.6.
The MySQL query optimizer needs to resolve the limit parameters to a constant before running the query, or it will not know how many rows to return.
You can't imbed a query result for a limit parameter