RedisSearch get max date in JSON - sql

I use RedisSearch to query my products
I want to get last 10 products changed
In SQL I can do that with:
Select top 10 * from products order by max(changedate) desc
How can I get the same result using RedisSearch?

You can use a range query with sortby.
FT.SEARCH products "#changedate:[somedate inf]" SORTBY changedate DESC
Please note that the smaller the date range you give, the faster the query will execute. You can fo [-inf inf] but that will not be efficiant.

Related

how to display last 10 numbers in sql

i have a table A with two column (number varchar(600),Date_ varchar(800))
now i have to display last 10 numbers order by Date_.
SELECT top(10) Number,Date FROM A ORDER BY Date_ DESC,
the problem is that for one month its showing result as desired,
but as soon next month start it not showing result as desired
i want the result like this.
10,2/2/2016
22,1/2/2016
10,31/1/2016
20,30/1/2016
30,29/1/2016
23,28/1/2016
20,27/1/2016
11,26/1/2016
18,25/1/2016
62,24/1/2016
56,23/1/2016
54,22/1/2016
44,21/1/2016
i am getting this result for --/1/2016 month but not for --/2/2016.
so kindly help.
Try the below script
SELECT top(10) Number,Date
FROM A
ORDER BY convert(datetime,Date,103) DESC
If you don't want to/can't change the structure of your table, then you need to use Parsing.
SELECT TOP 10 PARSE(Number AS int) AS Number,
PARSE(Date AS datetime2) AS Date
FROM A
ORDER BY Date DESC
You may need to do a PARSE in your ORDER BY as well.
Just a small change to your code should fix this
SELECT top(10) Number,Date FROM A ORDER BY cast(DATE_ as date) DESC.
Typically dates are stored as numbers in Microsoft world, i.e. 1/1/1900 is 1
1/2/1900 is 2
1/31/1900 is 31 and so on...
So changing your varchar to a date (provided there is no junk in the field) should fix this.

Understanding a Correlated Subquery

I want to create a query that returns the most recent date for a date field and the highest value of a integer field for each "assessment" record. What I think is required is a correlated subquery and using the MAX function.
example data would be as follows
the date field could have duplicate dates for each assessment but each duplicate date group would have a different the integer in the integer field.
eg
1256 2/6/14 0
1256 2/6/14 1
1256 1/6/14 0
4534 3/6/14 0
4534 3/6/14 1
4534 3/6/14 2
select assessment, Max(correctnum) maxofcorrectnum, dateeffect
from lraassm outerassm
where dateeffect =
(select MAX(dateeffect) maxofdateeffect
from pthdbo.lraassm innerassm
innerassm.assessment = outerassm.assessment
group by innerassm.assessment)
group by assessment, dateeffect
so my theory is that the inner query executes and gives the outer query the criteria for the dateeffect field in the outer query and then the outer query would return the maximum of the correctnum field for this dateeffect and also return its corresponding assessment and the dateeffect.
Could someone please confirm this is correct. How does the subquery handle the rows? what other ways are there to solve this problem? thanks
Your query is doing the right thing, but granted, the correlated subquery is a little difficult to understand. What the subquery does is, it filters the records based on assessment from the outer query and then returns the maximum dateeffect for that assessment. In fact, you don't need the group by clause on the correlated query.
These types of queries are where common when working with data in ERP systems, when you're only interested in "latest" records, etc. This is also known as a "top segment" type of query (which the query optimizer is sometimes able to figure out by itself). I've found, that on SQL Server 2005 or newer, it is a lot easier to use the ROW_NUMBER() function. The following query should return the same as yours, namely one record from lraassm for each assessment, that has the highest value of dateeffect and correctnum.
select * from (
select
assessment, dateeffect, correctnum,
ROW_NUMBER() OVER (
PARTITION BY assessment,
ORDER BY dateeffect DESC, correctnum DESC
) AS segment
from lraassm) AS innerQuery
where segment = 1
This is the query I worked out using my tables. But it will get you on the right track and you should be able to substitute your fields/tables in.
Select * from Decode
where updated_time = (Select MAX(updated_time)from DECODE)
That Query gives you every record that has the most recent updated_time. The next query will return the greatest entry_id value as well as the most recent updated_time from those Records
Select MAX(entry_id), updated_time from Decode
where updated_time = (Select MAX(updated_time)from DECODE)
group by updated_time
The result is 2 columns 1 record, 1st column is the Maximum value of entry id, the second is the most recent updated_time. Is that what you wanted to return?

Get a Row if within certain time period of other row

I have a SQL statement that I am currently using to return a number of rows from a database:
SELECT
as1.AssetTagID, as1.TagID, as1.CategoryID,
as1.Description, as1.HomeLocationID, as1.ParentAssetTagID
FROM Assets AS as1
INNER JOIN AssetsReads AS ar ON as1.AssetTagID = ar.AssetTagID
WHERE
(ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
I am wanting to do a query that will get the row with the oldest DateScanned from this query and also get another row from the database if there was one that was within a certain period of time from this row (say 5 seconds for an example). The oldest record would be relatively simple by selecting the first record in a descending sort, but how would I also get the second record if it was within a certain time period of the first?
I know I could do this process with multiple queries, but is there any way to combine this process into one query?
The database that I am using is SQL Server 2008 R2.
Also please note that the DateScanned times are just placeholders and I am taking care of that in the application that will be using this query.
Here is a fairly general way to approach it. Get the oldest scan date using min() as a window function, then use date arithmetic to get any rows you want:
select t.* -- or whatever fields you want
from (SELECT as1.AssetTagID, as1.TagID, as1.CategoryID,
as1.Description, as1.HomeLocationID, as1.ParentAssetTagID,
min(DateScanned) over () as minDateScanned, DateScanned
FROM Assets AS as1
INNER JOIN AssetsReads AS ar ON as1.AssetTagID = ar.AssetTagID
WHERE (ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
) t
where datediff(second, minDateScanned, DateScanned) <= 5;
I am not really sure of sql server syntax, but you can do something like this
SELECT * FROM (
SELECT
TOP 2
as1.AssetTagID,
as1.TagID,
as1.CategoryID,
as1.Description,
as1.HomeLocationID,
as1.ParentAssetTagID ,
ar.DateScanned,
LAG(ar.DateScanned) OVER (order by ar.DateScanned desc) AS lagging
FROM
Assets AS as1
INNER JOIN AssetsReads AS ar
ON as1.AssetTagID = ar.AssetTagID
WHERE (ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND (ar.DateScanned between 'LastScan' AND 'Now')
AND as1.TagID!='000000000000000000000000'
ORDER BY
ar.DateScanned DESC
)
WHERE
lagging IS NULL or DateScanned - lagging < '5 SECONDS'
I have tried to sort the results by DateScanned desc and then just the top most 2 rows. I have then used the lag() function on DateScanned field, to get the DateScanned value for the previous row. For the topmost row the DateScanned shall be null as its the first record, but for the second one it shall be value of the first row. You can then compare both of these values to determine whether you wish to display the second row or not
more info on the lagging function: http://blog.sqlauthority.com/2011/11/15/sql-server-introduction-to-lead-and-lag-analytic-functions-introduced-in-sql-server-2012/

SQL AVG() function returning incorrect values

I want to use the AVG function in sql to return a working average for some values (ie based on the last week not an overall average). I have two values I am calculating, weight and restingHR (heart rate). I have the following sql statements for each:
SELECT AVG( weight ) AS average
FROM stats
WHERE userid='$userid'
ORDER BY date DESC LIMIT 7
SELECT AVG( restingHR ) AS average
FROM stats
WHERE userid='$userid'
ORDER BY date DESC LIMIT 7
The value I get for weight is 82.56 but it should be 83.35
This is not a massive error and I'm rounding it when I use it so its not too big a deal.
However for restingHR I get 45.96 when it should be 57.57 which is a massive difference.
I don't understand why this is going so wrong. Any help is much appreciated.
Thanks
Use a subquery to separate selecting the rows from computing the average:
SELECT AVG(weight) average
FROM (SELECT weight
FROM stats
WHERE userid = '$userid'
ORDER BY date DESC
LIMIT 7) subq
It seems you want to filter your data with ORDER BY date DESC LIMIT 7, but you have to consider, that the ORDER BY clause takes effect after everything else is done. So your AVG() function considers all values of restingHR from your $userId, not just the 7 latest.
To overcome this...okay, Barmar just posted a query.

SQL Difference between using two dates

My database has a table called 'clientordermas'. Two columns of that table are as follows.
execid and filledqty.
Three records of those two fields are as follows.
E02011/03/12-05:57_24384 : 1000
E02011/03/12-05:57_24384 : 800
E02011/03/09-05:57_24384 : 600
What i need to do is get the filledqty diffrence btween latest date and 1 before latest date which is 400(1000-400).
I have extracted the date from the execid as follows:
(SUBSTR (execid, 3, 10)
I tried so hard but but I was unable to write the sql query to get 400. Can someone please help me to do this???
P.S I need to select maximum filled quantity from the same date. That is 1000 not, 800.
You can use window functions to access "nearby" rows, so if you first clean up the data in a subquery and then use window functions to access the next row, you should get the right results. But unless you have an index on substr(execid, 3, 10), this is going to be be slow.
WITH datevalues AS
(
SELECT max(filledqty) maxfilledqty, substr(execid, 3, 10) execiddate
FROM clientordermas
GROUP BY substr(execid, 3, 10)
)
SELECT
execiddate,
maxfilledqty -
last_value(maxfilledqty) over(ORDER BY execiddate DESC ROWS BETWEEN 0 PRECEDING AND 1 FOLLOWING)
FROM datevalues
ORDER BY execiddate DESC;
WITH maxqtys AS (
SELECT substr(a.execid,3,10) AS date, MAX(a.filledqty) AS maxqty
FROM clientordermas a
GROUP BY substr(a.execid,3,10)
)
SELECT a.maxqty-b.maxqty
FROM maxqtys a, maxqtys b
WHERE a.date <> b.date AND ROWNUM=1
ORDER BY a.date DESC, b.date DESC
This first creates a subquery (maxqty) which contains the max filledqty for each unique date, then cross join this subquery to itself, excluding the same rows. This results in a table containing pairs of dates (excluding the same dates).
Sort these pairs by date descending, and the top row till contain the last and 2nd-to-last date, with the appropriate quantities.