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;
Related
I want to group my data by Date and then find "Value" for MAX("SeqNumber"). How can I do this in an aggregate query.
I tried the below, but it gives and error.
Column 'MyTable.SeqNumber' is invalid in the select list because it is
not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 22 Column 'MyTable.Value' is invalid
in the select list because it is not contained in either an aggregate
function or the GROUP BY clause.
Columns:
Date: date
Time: time
Value: float
Code: varchar <<Added in EDIT
SeqNumber: int
Edited query:
SELECT MAX(case [Code] when 'GOLD' then [Value] end) AS BestGold,
MAX(case [Code] when 'SILVER' then [Value] end) as BestSilver
(CASE WHEN [SeqNumber]=MAX([SeqNumber]) THEN [Value] END) AS HIGHEST << Problem
FROM [MyTable]
GROUP BY [Date]
you can achieve this by using using group by and sub query -
select t1.*
from [MyTable] t1 join
( SELECT
MAX([SeqNumber]) as MX_SeqNumber -- you can add your additional columns here
FROM [MyTable]
GROUP BY [Date] ) as t2
on t1.[SeqNumber] = t2.MX_SeqNumber
WITH CTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY Sequence DESC) AS RN
FROM YourTable)
SELECT [Value] AS Highest
FROM CTE
WHERE RN = 1;
I have a stored procedure in the works, however, I'm missing a few pieces of data when I run it. I know the reason why, but I'm having a hard time figure it out... this is my code:
INSERT INTO tempIntake (Pop, PlanID, PopFull, ApptDate, [1stAppt], Followup, Rn, UserID)
SELECT Pop, PlanID, PopFull, InterviewDate, 1 stAppt, Followup, rn, #UserID
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY PlanID ORDER BY AddedDate ASC) AS rn
FROM VInfo
WHERE AddedDate IS NOT NULL
) t
WHERE rn = 1 AND interviewdate >= #fromDate AND interviewDate <= #toDate
So what I'm trying to do here is this....For some PLANID's I don't have an added date. Because I'm filtering by the AddedDate and in case is null - this data does not come up - even though I need it to be shown. In this case I'd like to make it a dummy date like '1/1/2016' this way, when the actually AddedDate becomes available in the table, it will be used instead of the dummy date.
If AddedDate can't be "bigger" then GETDATE(), you can use ISNULL(AddedDate,GETDATE())) and remove the where AddedDate is not null condition:
Insert into tempIntake(Pop, PlanID, PopFull, ApptDate, 1stAppt, Followup, Rn, UserID)
select
Pop, PlanID, PopFull, InterviewDate, 1stAppt, Followup, rn, #UserID
from
(Select
*,
row_number() over (partition by PlanID order BY ISNULL(AddedDate,GETDATE())) as rn
from
VInfo) t
where
rn = 1
and interviewdate >= #fromDate
and interviewDate <= #toDate
I have a query which retrieves latest data from table with pagination which is working fine.
But once the data is older from current time it should also appear but after the latest one.
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
WHERE A.RowNumber BETWEEN #RowStart AND #RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC
I'm not sure if I'm exactly getting what you're looking for, but this should get you something close. I created a CTE with two computed columns:
BeforeAfter, which determines if the date happens before or after the passed in date
AbsDiff, which gives the absolute value of the date diff.
Then, I just sort using those two fields:
DECLARE #current datetime = GETDATE()
;WITH cteMessages AS
(
SELECT UserId, FirstName, LastName, PostDate,
CASE WHEN PostDate < #current THEN 1 ELSE 0 END AS BeforeAfter,
ABS(DATEDIFF(SECOND, #current, PostDate)) AS AbsDiff
FROM Messages
)
SELECT * FROM cteMessages
ORDER BY BeforeAfter, AbsDiff
From those results, you can see how they are sorted first by messages newer than the passed in date, then in reverse order from older messages. You can substitute that order by into your Row_Number function.
You cant do Order By ASC and DESC on the Same column of a Table if you do you will get the following Error
Msg 169, Level 15, State 1, Line 1 A column has been specified more
than once in the order by list. Columns in the order by list must be
unique.
If you want it you may do using Join of the same Table and order by the same column like
SELECT A.UserId,A.FirstName,A.LastName,A.PostDate
(SELECT ROW_NUMBER() OVER(ORDER BY CAST(M.PostDate AS DATETIMEOFFSET) DESC) AS 'RowNumber'
M.UserId,
M.FirstName,
M.LastName,
M.PostDate
FROM Messages AS M
Where M.PostDate >= GetDate()
) A
Inner Join Messages AS Msg on Msg.UserId=A.UserId
WHERE A.RowNumber BETWEEN #RowStart AND #RowEnd
ORDER BY CAST(A.PostDate AS DATETIMEOFFSET) DESC,
CAST(Msg.PostDate AS DATETIMEOFFSET) ASC
I think you should remove the following line
Where M.PostDate >= GetDate()
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;
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