This is login table where I need to display username with count they have logged in to application and split it by month wise the data to show the count based on month wise
Table name: LoginInformation
UserName Count Datetime
---------------------------------
Test-1 1 2017-06-02
Test-1 1 2017-07-20
Test-1 1 2017-09-20
Test-1 1 2017-09-20
Test-1 1 2017-09-15
Test-1 1 2017-10-22
Test-1 1 2017-10-23
Test-2 1 2017-06-12
Test-2 1 2017-06-12
Test-2 1 2017-07-24
Test-2 1 2017-09-23
Test-2 1 2017-09-29
Test-2 1 2017-09-11
Test-2 1 2017-10-12
Test-2 1 2017-10-19
Test-2 1 2017-10-21
I need he result to be displayed as
UserName Count June July Sept Oct
----------------------------------------
Test-1 7 1 1 3 2
Test-1 7 2 1 3 3
;WITH ctePrepared AS (
SELECT
UserName
,TotalCount = SUM([Count]) OVER (PARTITION BY UserName)
,[MonthName] = DATENAME(MONTH,[Datetime])
,[Count]
FROM
#Table
)
ORDER BY
UserName DESC
SELECT *
FROM
ctePrepared t
PIVOT
(
SUM([Count])
FOR [MonthName] IN (January,February,March,April,May,June,July,August,September,October,November,December)
) pvt
the test data script if needed:
DECLARE #Table AS TABLE (UserName VARCHAR(50), [Count] INT, [Datetime] DATETIME)
INSERT INTO #Table
VALUES ('Test-1',1,'2017-06-02')
,('Test-1',1,'2017-07-20')
,('Test-1',1,'2017-09-20')
,('Test-1',1,'2017-09-20')
,('Test-1',1,'2017-09-15')
,('Test-1',1,'2017-10-22')
,('Test-1',1,'2017-10-23')
,('Test-2',1,'2017-06-12')
,('Test-2',1,'2017-06-12')
,('Test-2',1,'2017-07-24')
,('Test-2',1,'2017-09-23')
,('Test-2',1,'2017-09-29')
,('Test-2',1,'2017-09-11')
,('Test-2',1,'2017-10-12')
,('Test-2',1,'2017-10-19')
,('Test-2',1,'2017-10-21')
Related
I have the following Oracle table
PersonID
VisitedOn
1
1/1/2017
1
1/1/2018
1
1/1/2019
1
1/1/2020
1
2/1/2020
1
3/1/2020
1
5/1/2021
1
6/1/2022
2
1/1/2015
2
1/1/2017
2
1/1/2018
2
1/1/2019
2
1/1/2020
2
2/1/2020
3
1/1/2017
3
1/1/2018
3
1/1/2019
3
1/1/2020
3
2/1/2020
3
3/1/2020
3
5/1/2021
I try to write a query to return the Nth oldest visit of each person.
For instance if I want to return the 5th oldest visit (N=5) the result would be
PersonID
VisitDate
1
1/1/2020
2
1/1/2017
3
1/1/2019
I think this will work:
Ran test with this data:
create table test (PersonID number, VisitedOn date);
insert into test values(1,'01-JAN-2000');
insert into test values(1,'01-JAN-2001');
insert into test values(1,'01-JAN-2002');
insert into test values(1,'01-JAN-2003');
insert into test values(2,'01-JAN-2000');
insert into test values(2,'01-JAN-2001');
select personid, visitedon
from (
select personid,
visitedon,
row_number() over ( partition by personid order by visitedon ) rn
from test
)
where rn=5
What this does is use an analytic function to assign a row number to each set of records partitioned by the person id, then pick the Nth row from each partitioned group, where the rows in each group are sorted by date. If you run the inner query by itself, you will see where the row_number is assigned:
PERSONID VISITEDON RN
1 01-JAN-00 1
1 01-JAN-01 2
1 01-JAN-02 3
1 01-JAN-03 4
2 01-JAN-00 1
2 01-JAN-01 2
First, thanks for your time and your help!
I have two tables:
Table 1
PersId name lastName city
---------------------------------------
1 John Smith Tirana
2 Leri Nice Tirana
3 Adam fortsan Tirana
Table 2
Id PersId salesDate
--------------------------------------------
1 1 2017-01-22 08:00:40 000
2 2 2017-01-22 09:00:00 000
3 1 2017-01-22 10:00:00 000
4 1 2017-01-22 20:00:00 000
5 3 2017-01-15 09:00:00 000
6 1 2017-01-21 09:00:00 000
7 1 2017-01-21 10:00:00 000
8 1 2017-01-21 18:55:00 000
I would like to see the first recent sales between two dates according to each city for each day I want to bring it empty if I do not have a sale
SalesDate > '2017-01-17 09:00:00 000'
and SalesDate < '2017-01-23 09:00:00 000'
Table 2, id = 5 because the record is not in the specified date range
If I wanted my results to look like
Id PersId MinSalesDate MaxSalesDate City
-----------------------------------------------------------------------------
1 1 2017-01-22 08:00:40 000 2017-01-22 20:00:00 000 Tirana
2 2 2017-01-22 09:00:00 000 null Tirana
3 3 null null Tirana
4 1 2017-01-21 09:00:00 000 2017-01-21 18:55:00 000 Tirana
You dont identify how to get ID in the result. You appear to just want Row_Number(). I will leave that out, but this should get you started. You may have to work out conversion issues in the data range check, and I havent checked the query for syntax errors, I will leave that to you.
Select T1.PersId, City
, Min(T2.salesDate) MinSalesDate
, Max(T2.salesDate) MaxSalesDate
From Table1 T1
Left Join Table2 T2
On T1.PersId = T2.PersId
And T2.salesDate Between '2017-01-17 09:00:00 000' And < '2017-01-23 09:00:00 000'
Group BY T1.PersId, T2.City
Try the following using row_number to get min and max sale dates:
SELECT
T2.Id, T1.PersId, T2.MIN_salesDate, T2.MAX_salesDate, T1.City
FROM Table1 T1
LEFT JOIN
(
SELECT MIN(Id) as Id, PersId, MIN(salesDate) as MIN_salesDate, MAX(salesDate) as MAX_salesDate
FROM
(
SELECT
*
,ROW_NUMBER() OVER (PARTITION BY PersId ORDER BY salesDate ASC) as RNKMIN
,ROW_NUMBER() OVER (PARTITION BY PersId ORDER BY salesDate DESC) as RNKMAX
FROM Table2 T2
WHERE salesDate Between '2017-01-17 09:00:00 000' And '2017-01-23 09:00:00 000'
) temp
WHERE RNKMIN = 1 or RNKMAX = 1
GROUP BY PersId
) T2
on T1.PersId = T2.PersId
I have a table like the below:
ID, MachineID Customer TimeStamp Counter type
1 A ABC 2017-10-25 3:08PM 1952 1
2 A ABC 2017-10-25 3:00PM 1940 1
3 A ABC 2017-10-25 12:05PM 1920 1
4 A ABC 2017-10-25 9:00AM 1900 1
5 B BCD 2017-10-25 3:11PM 1452 1
6 B BCD 2017-10-25 3:10PM 1440 1
7 B BCD 2017-10-25 12:15PM 1420 1
8 B BCD 2017-10-25 9:30AM 1400 1
9 A ABC 2017-10-23 3:08PM 1900 1
10 A ABC 2017-10-23 3:00PM 1840 1
11 A ABC 2017-10-23 12:05PM 1820 1
12 A ABC 2017-10-23 9:00AM 1800 1
13 B BCD 2017-10-23 3:11PM 1399 1
14 B BCD 2017-10-23 3:10PM 1340 1
15 B BCD 2017-10-23 12:15PM 1320 1
16 B BCD 2017-10-23 9:30AM 1300 1
The counter value increases whenever there is a click. I am trying to calculate number of clicks for each day by taking maximum counter value at the end of day and subtract the previous day maximum counter value and so on.
How do I do this in SQL server. Have to repeat this for each customer and Machine
Try this. I am using LAG function in order to achieve this. You can use where clause to filter out specific date you want :
Create table #counter(ID int, timeStamp datetime, Counter int, type int)
insert into #counter values
(1, '20171024 3:08PM' ,1952, 1),
(1, '20171025 3:00PM' ,1964, 1)
Select iq.*, (iq."counter" - iq.yesterday_counter) as today_count
from
(select id,
cast("timestamp" as date) as today_date,
"counter",
LAG("counter") over (order by cast("timestamp" as date)) yesterday_counter
from #counter
) iq
output:
id today_date counter yesterday_counter today_count
----------- ---------- ----------- ----------------- -----------
1 2017-10-24 1952 NULL NULL
1 2017-10-25 1964 1952 12
A SQL query to get the max counter for each day is:
SELECT CAST(timeStamp as date) AS [dateval]
,MAX(Counter) AS [maxCounter]
FROM YOURDATASET
GROUP BY CAST(timeStamp as date)
This is converting the datetime to date- cutting out the time, then taking the max(Counter).
One method to get the difference is to save the result in a temp datastructure, then query it to get the difference.
The question is whether your previous date is exactly the previous day, or if you're skipping days between counts, or taking the weekend off, etc. In that case you have to select the greatest previous date to the date being examined.
ex.
DECLARE #temp TABLE (dateval date, maxCounter int)
INSERT INTO #temp(dateval, maxCounter)
SELECT CAST(timeStamp as date) AS [dateval]
,MAX(Counter)
FROM YOURDATASET
GROUP BY CAST(timeStamp as date)
SELECT T.dateval
,T.dateval
-
(SELECT maxCounter
FROM #temp T2
WHERE T2.dateVal = (SELECT MAX(dateVal)
FROM #temp T3
WHERE T3.dateVal < T1.dateVal
)
) AS [Difference]
FROM #temp T
ORDER BY T.dateval
This post is really similar to my question:
SQL Server : how many days each item was in each state
but I dont have the column Revision to see wich is the previous state, and also I want to get the full time of a status, I b
....
I'm want to get how long one item has been in one status in general, my table look like this:
ID DATE STATUS
3D56B7B1-FCB3-4897-BAEB-004796E0DC8D 2016-04-05 11:30:00.000 1
3D56B7B1-FCB3-4897-BAEB-004796E0DC8D 2016-04-08 11:30:00.000 13
274C5DA9-9C38-4A54-A697-009933BB7B7F 2016-04-29 08:00:00.000 5
274C5DA9-9C38-4A54-A697-009933BB7B7F 2016-05-04 08:00:00.000 4
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 2016-04-14 07:50:00.000 1
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 2016-04-21 14:00:00.000 2
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 2016-04-23 12:15:00.000 3
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 2016-04-23 16:15:00.000 1
BF122AE1-CB39-4967-8F37-012DC55E92A7 2016-04-05 10:30:00.000 1
BF122AE1-CB39-4967-8F37-012DC55E92A7 2016-04-20 17:00:00.000 5
I want to get this
Column 1 : ID Column 2 : Status Column 3 : Time with the status
Column 3 : Time with the status
= NextDate - PreviosDate + 1
if is the last Status, is count as 1
if is more than one Status on the same day, I get the Last one (u can say that only mather the last Status of the day)
by ID, Status must be unique
I should look like this:
ID STATUS TIME
3D56B7B1-FCB3-4897-BAEB-004796E0DC8D 1 3
3D56B7B1-FCB3-4897-BAEB-004796E0DC8D 13 1
274C5DA9-9C38-4A54-A697-009933BB7B7F 5 5
274C5DA9-9C38-4A54-A697-009933BB7B7F 4 1
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 1 8
A70A66DC-9D9E-49BE-93CF-00F9E3E06CE2 2 2
BF122AE1-CB39-4967-8F37-012DC55E92A7 1 15
BF122AE1-CB39-4967-8F37-012DC55E92A 5 1
Thanks to #ConradFrix comments, this is how works ..
WITH CTE
AS
(
SELECT
ID,
STATUS,
DATE,
LEAD(DATE, 1) over (partition by ID order by DATE) LEAD,
ISNULL(DATEDIFF(DAYOFYEAR, DATE,
LEAD(DATE, 1) over (partition by ID order by DATE)), 1) DIF_BY_LEAD
FROM TABLE_NAME
)
SELECT ID, STATUS, SUM(DIF_BY_LEAD) AS TIME_STATUS
FROM CTE GROUP BY ID, STATUS
ORDER BY ID, STATUS
Here is the table structure:
tblApplicants:
applicantID (index) | ApplyingForYear (nvarchar)
------------------------------------------------------
1 2013/14
11 2013/14
13 2013/14
12 2013/14
15 2013/14
21 2012/13
tblApplicantSchools_shadow:
id (index) | applicantID | updated (datetime) | statusID (int) | schoolID (int)
-----------------------------------------------------------------------------------------------------
1 11 2012-09-24 00:00:00.000 3 2
1 13 2012-10-24 00:00:00.000 4 2
2 15 2012-11-24 00:00:00.000 3 4
3 13 2012-03-24 00:00:00.000 4 3
4 12 2012-09-24 00:00:00.000 4 1
5 21 2012-11-03 00:00:00.000 5 2
6 11 2012-09-04 00:00:00.000 4 4
What I need to do is:
get all applicants, that have an ApplyingForYear of '2013/14' in tblApplicants
have a statusID of 4
I only want to count them once - even if they appear twice or more in tblApplicantschools_show
group the number of distinct applicants (as per the above) - by the updated date column (grouped by week)
So based on the sample data above, there should be 3 rows that come out, (because ApplicantID 13 appears twice and I only want him once).
This is how the result should look:
Datesubmitted TotalAppsPerWeek
-------------------------------------------------------
2012-10-24 00:00:00.000 1
2012-09-24 00:00:00.000 1
2012-09-04 00:00:00.000 1
This is what I have so far - but it results in 4 rows, not 3 :(
select
DATEADD(ww,(DATEDIFF(ww,0,[tblApplicantSchools_shadow].updated)),0) AS Datesubmitted,
count(DISTINCT [tblApplicantSchools_shadow].applicantID) as TotalAppsPerWeek
FROM tblApplicants
INNER JOIN tblApplicantSchools_shadow
ON tblApplicantS.ApplicantID = tblApplicantSchools_shadow.applicantID
WHERE
ApplyingForYear = '2013/14'
AND [tblApplicantSchools_shadow].statusID = 4
GROUP BY
DATEADD(ww, (DATEDIFF(ww, 0, [tblApplicantSchools_shadow].updated)), 0)
And here is a Fiddle: http://sqlfiddle.com/#!3/3aa61/42
From your title, I'm assuming the one row you want from each applicant is the one with the smallest id. You can select one row per applicant ID with the ROW_NUMBER() function:
;with latestApplication AS
(
SELECT DATEADD(ww,(DATEDIFF(ww,0,[tblApplicantSchools_shadow].updated)),0)
AS Datesubmitted,
[tblApplicantSchools_shadow].applicantID,
ROW_NUMBER() OVER (PARTITION BY [tblApplicantSchools_shadow].applicantID
ORDER BY [tblApplicantSchools_shadow].id)
AS rn
FROM tblApplicants
INNER JOIN tblApplicantSchools_shadow
ON tblApplicantS.ApplicantID = tblApplicantSchools_shadow.applicantID
WHERE ApplyingForYear = '2013/14'
AND [tblApplicantSchools_shadow].statusID = 4
)
select Datesubmitted, COUNT(1) AS TotalAppsPerWeek
FROM latestApplication
WHERE rn = 1
group by Datesubmitted
order by Datesubmitted DESC
http://sqlfiddle.com/#!3/3aa61/57