I have data like this:
Value|Date
0,055|2015-01-01 12:30:00.000
0,024|2015-01-01 15:30:00.000
0,023|2015-01-02 13:30.00.000
I need to get the max value per day and the time when it happens. So far I can get the max value without problems but because of the group by I only get the day without time. How can I get the complete datetime grouping by day?
This should work:
;WITH CTE AS
(
SELECT Value,
[Date],
RN = ROW_NUMBER() OVER(PARTITION BY CONVERT(DATE,[Date]) ORDER BY Value DESC)
FROM dbo.YourTable
)
SELECT Value,
[Date]
FROM CTE
WHERE RN = 1;
Related
I have a SQL query for 'SQL Server' which 'count()' based on column 'id'.
And I also want to 'RANK' based on the value of COUNT(). But when I try the below query,
I get error sayign 'Invalid column names 'IdCount''
SELECT
[id],
COUNT(*) AS IdCount,
RANK() OVER (
ORDER BY IdCount
) CountRank
FROM myTable
where DATEDIFF(day,[Time],GETDATE()) < 30
GROUP BY [id]
Can you please tell me how can I reference the COUNT() result?
Thank you.
You can't reference an expression's alias in a window function at the same scope. Also, I think you want the RANK() to be applied from the highest count, not the lowest. Finally, you should never apply calculations like DATEDIFF against a column. How about:
DECLARE #start date = DATEADD(DAY, -30, GETDATE());
SELECT id, IdCount,
CountRank = RANK() OVER (ORDER BY IdCount DESC)
FROM
(
SELECT id, COUNT(*)
FROM dbo.myTable
WHERE [Time] >= #start
GROUP BY id
) AS x;
I have a table named
Ship(Date datetime,name varchar(50),Type char(1)).
In table Ship The "Date" Column is of datetime datatype. I want to select rows from ship table when minute value in Date column (of Datetime datatype) changes. For this i used the following query:
;WITH x AS
(
SELECT Name, Date,Type, rn = ROW_NUMBER() OVER
(PARTITION BY Date ORDER BY Date desc)
FROM Ship
)
SELECT * FROM x WHERE rn = 1
But the desired output is not coming. The Result coming is:
Date Name Type
2017-05-08 14:59:13.000 sumit A
2017-05-08 14:59:23.000 sumit B
2017-05-08 14:59:33.000 sumit A
2017-05-08 15:00:05.000 Ajay B
2017-05-08 15:00:13.000 Deep G
2017-05-08 15:01:03.000 Suri D
2017-05-08 15:01:13.000 Faiz E
Here in above output those rows are also coming when there is a change in second value of Date column. But i want to select rows when there is change in minute value of Date Column.Can anyone solve this?
You could use datediff minute on partition by clause
;WITH x AS
(
SELECT Name, Date,Type, rn = ROW_NUMBER() OVER
(PARTITION BY datediff(min,0,[Date]) ORDER BY Date desc)
FROM Ship
)
SELECT * FROM x WHERE rn = 1
Or it is shorter version
SELECT TOP 1 WITH TIES
Name, Date,Type
FROM Ship
ORDER BY ROW_NUMBER() OVER (PARTITION BY datediff(min,0,[Date]) ORDER BY [date] desc)
Can you add the DATEPART in the PARTITION BY to get the change in the minutes section only.
;WITH x AS
(
SELECT Name, Date,Type, rn = ROW_NUMBER() OVER
(PARTITION BY DATEPART(N, Date) ORDER BY Date desc)
FROM Ship
)
SELECT * FROM x WHERE rn = 1
Refer the Demo: http://rextester.com/YZW84894
This is a question using SQL Server. Is there a more elegant way of doing this?
Considering a table mytable (I'm using Unix timestamps, I've converted these to readable dates for ease of reading)
ID Foreign_ID Date
-------------------------
1 1 01-Jul-15
2 2 01-Sep-16
3 3 05-Aug-16
4 2 01-Sep-15
I would like to extract the Foreign_ID where the most recent record's (highest ID) date is in a range, which is this example is the 1st January 2016 to 31st December 2016. The following works if substituting the dates for timestamps:
select distinct
Foreign_ID
from
mytable l1
where
(select top 1 Date
from mytable l2
where l2.Foreign_ID = l1.Foreign_ID
order by ID desc) >= **1 Jan 2016**
and
(select top 1 Date
from mytable l2
where l2.Foreign_ID = l1.Foreign_ID
order by ID desc) <= **31 Dec 2016**
That should only return Foreign_ID = 3. A simpler query would also return Foreign_ID 2 which would be wrong, as it has a more recent record dated out of the above ranges
This will all form part of a bigger query
Assuming SQL Server 2005+, you can use ROW_NUMBER:
WITH CTE AS
(
SELECT *,
RN = ROW_NUMBER() OVER( PARTITION BY Foreign_ID
ORDER BY ID DESC)
FROM dbo.YourTable
WHERE [Date] >= '01-Jan-2016' -- you need to use the right
AND [Date] <= '31-Dec-2016' -- date format here
)
SELECT Foreign_ID
FROM CTE
WHERE RN = 1;
If it's SQL Server 2008+, you can use this:
select foreign_id
from (
select foreign_id, row_number() over (order by id desc) as rseq
from myTable
where Date >= value1 and Date <= value2
) as x
where rseq = 1
Just fill in the date values, and you might have to put brackets or quotes around the column named "Date", since it is also a keyword.
I'm looking for a way to fetch at least 20 rows, regardless of the date or all rows with a date greater than a set date (whichever of the 2 fetches the most rows).
For example:
SELECT *
FROM table1
WHERE the_date >= '2014-11-01'
ORDER BY the_date DESC
will give me what I want, but if this returns less than 20 rows then I want to keep going before that date until I get 20 (or until there are no more rows - whichever comes first).
I could just select all and take the ones I need programatically, but I'm trying to avoid that as that would be a major change to the actual code in many places.
Can this be done?
Note: I am using SQL Server 2008.
Here's an approach:
select *
from
(
select row_number() over (order by the_date desc) num, t.*
from table1 t
) i
where i.the_date >= '2014-11-01'
or i.num < 21
Very strange requirement but something like this should work.
DECLARE #Date date = '2014-11-01';
with MyResults as
(
SELECT *, 1 as RowNum
FROM table1
WHERE (the_date >= #Date )
UNION ALL
SELECT top 10 *, ROW_NUMBER() over(order by the_date desc)
FROM table1
order by the_date desc
)
Select *
from MyResults
where RowNum <= 20
The right answer was almost there, but the user has removed it, so here it is again:
SELECT *
FROM table1
WHERE the_date >= '2014-11-01'
union
SELECT top 20 *
FROM table1
ORDER BY the_date desc
The removed answer had union all
This answer has a problem with duplicate dates , but with the data I have that is not an issue
Is there any way to use ROW_NUMBER() in SQL without using OVER, because I want to use sorting.
I have a Grid with multiple sortable columns with configurable rows. In my scenario order by is variable that's why I am not able to put order by using ROWNUM.
select ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) as number from Task order by RuleId
I approached this using a different logic. Instead of checking for every single day and verifying it is a weekday or a holiday I create a table which lists only the business days and then take the nth value.
CREATE OR REPLACE FUNCTION add_n_working_days (
start_date DATE, working_days PLS_INTEGER
) RETURN DATE AS
l_end_date DATE := start_date;
l_counter pls_integer := 0;
BEGIN
SELECT
business_day
INTO l_end_date
FROM
(
WITH
dates AS
(SELECT start_date + level - 1 as dt FROM dual CONNECT BY level < 100)
,weekdates AS
(SELECT dt as weekday FROM dates WHERE TO_CHAR(dt,'fmdy') NOT IN ('sat','sun'))
,business_days AS
(
SELECT weekday as business_day FROM weekdates
MINUS
SELECT holiday FROM so_holidays
)
SELECT business_day, ROW_NUMBER() OVER (ORDER BY 1) as rn from business_days
)
WHERE rn = working_days + 1;
RETURN l_end_date;
END add_n_working_days;
If working_days gets too high then I suggest making that value 100 a variable.
select
a.City,
a.len
from
(
select city,length(city) AS len,
row_number()over(order by length(city) desc, city) as hi,
row_number()over(order by length(city), city) as lo
from
STATION) as a where (a.lo=1 or a.hi=1);