简体   繁体   中英

create a statistics table using datetime MSSQL Query

I have little table which gives me a very hard time:

Person    datetime1                   datetime2
Eric      2012-10-01 09:00:05.000     2012-10-01 22:00:00.000
Anna      2012-10-02 06:00:05.000     2012-10-03 12:00:05.000
Richard   2012-10-03 09:00:05.000     2012-10-04 02:00:05.000
Chuck     2012-10-01 12:00:05.000     2012-10-01 23:00:05.000

I am trying to write a query, which gives me statistics table. This table contains information about when a user logged in and out (daily granularity):

Date        logged_in  logged_off
2012-10-01  2          2
2012-10-02  1          0
2012-10-03  1          1
2012-10-04  0          1

According to my research, a pivot command could solve the problem?

select Person,
SUM(case when datetime1 = '2012-10-01' then 1 else 0 end) as [loggeed_in],
SUM(case when datetime2 = '2012-10-01'  then 1 else 0 end) as [logged_of]
from table
group by Person

This is not working... Do you have any ideas?

This will fix the current query, but don't know if it will solve the whole problem...

select Person,
SUM(case when convert(varchar(10), datetime1, 111) = '2012/10/01' then 1 else 0 end) as [loggeed_in],
SUM(case when convert(varchar(10), datetime2, 111) =  '2012/10/01'  then 1 else 0 end) as [logged_of]
from table
group by Person

EDIT: I believe this will better suit requirements...

SELECT 
    [Date] = dt,
    logged_in = (
        SELECT COUNT(*)
        FROM table1
        WHERE convert(varchar(10), datetime1, 111) = convert(varchar(10), dt, 111)),
    logged_off = (
        SELECT COUNT(*)
        FROM table1
        WHERE convert(varchar(10), datetime2, 111) = convert(varchar(10), dt, 111))
FROM (
    SELECT TOP 1000
        row_number() OVER(ORDER BY (SELECT 0)) AS N
        FROM master.dbo.syscolumns sc1, master.dbo.syscolumns sc2) tally
    CROSS APPLY(
        SELECT dt = DATEADD(dd, tally.N - 1, '2012-10-1')) tallydt
WHERE dt BETWEEN (SELECT MIN(dateadd(dd, -1, datetime1)) FROM table1) AND (SELECT MAX(datetime2) FROM table1)
GROUP BY dt 
ORDER BY dt

Here is the working solution:

WITH O AS (
SELECT
CAST([login Date & Time] AS DATE) loginDate
,COUNT(*) logined
 FROM table
 GROUP BY CAST([login Date & Time] AS DATE)
 ), C AS (
SELECT 
CAST([Close Date & Time] AS DATE) CloseDate
,COUNT(*) Closed
 FROM table
WHERE [Close Date & Time] IS NOT NULL
GROUP BY CAST([Close Date & Time] AS DATE)
 )
 SELECT
COALESCE(C.CloseDate, O.loginDate) TheDate
--,O.loginDate
--,C.CloseDate
,O.logined
,C.Closed
  FROM O 
  FULL JOIN C
 ON O.loginDate = C.CloseDate
 ORDER BY TheDate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM