SQL server 2000 pulling count grouped by time - sql-server

I have a table like below.
Date | Time | connect |
2013-08-23 00:00:00.000 | 05.26.13 | 1 |
2013-08-23 00:00:00.000 | 05.32.11 | 1 |
2013-08-23 00:00:00.000 | 05.26.13 | 1 |
2013-08-23 00:00:00.000 | 06.02.52 | 1 |
2013-08-23 00:00:00.000 | 06.41.09 | 1 |
2013-08-23 00:00:00.000 | 06.43.12 | 1 |
2013-08-23 00:00:00.000 | 06.52.09 | 1 |
2013-08-23 00:00:00.000 | 06.57.39 | 1 |
2013-10-21 00:00:00.000 | 03.58.35 | 1 |
2013-10-21 00:00:00.000 | 04.02.18 | 1 |
2013-10-21 00:00:00.000 | 04.12.02 | 1 |
2013-10-21 00:00:00.000 | 04.41.36 | 1 |
2013-10-21 00:00:00.000 | 11.12.27 | 1 |
2013-10-22 00:00:00.000 | 11.58.35 | 1 |
I want to get the count of connect that fall in each hour, grouped by date.
Count falling between 1:00 to 1:59, 2:00 to 2:59 and so on. The below is model of the output that I require.
Date | Count(between 4.00.00 to 4.59.59) | Count(between 5.00.00 to 5.59.59) | Count(between 6.00.00 to 6.59.59) |Count(between 11.00.00 to 11.59.59) |
2013-08-23 00:00:00.000 | 0 | 3 | 5 | 0 |
2013-10-21 00:00:00.000 | 3 | 1 | 0 | 1 |
2013-10-22 00:00:00.000 | 0 | 0 | 0 | 1 |

You can just use group by with the date time functions if you don't care about missing 0 row counts, but if you are concerned, use the tally table example Jeff mentions in 2nd page of this forum post: http://www.sqlservercentral.com/Forums/Topic288581-8-1.aspx Both examples in this post, but it note it is by half hour, should be easy to convert to hour.

This is what I want.
by Matt Watson
SELECT [Hourly], COUNT(*) as [Count] FROM (SELECT dateadd(hh, datediff(hh, '20010101', [date_created]), '20010101') as [Hourly] FROM table) idat GROUP BY [Hourly]

Related

SQL Get 12 weeks as columns

i need help on the following.
I have the basic query below:
select count(transactions)
from tx
where customer = 'AA'
This gives me a count of all transactions for the relevant client.
What I want is a query that gives me the same output but broken down into the LATEST last 12 weeks (Monday-Sunday is one full week). These values should be presented as 12 columns with the header of each column presented as the last date of the week (ie Sunday's date).
Furthermore the total transactions are split into status- failed and success. I would like the rows of the transactions to be failed and success so the final table would look like this:
25/03/2018 (week 1)| 01/04/2018| ........ |17/06/2018 << (week 12)
Success 100 | 200 | ........ | 150
Failed 3 | 4 | ........ | 6
Any ideas how this can be done?
Thanks you in advance
Returning pivoted data is usually a lot more hassle than it is worth and you should just leave this up to your presentation layer, which will handle your dynamic columns with much more grace. Regardless of the presentation layer you are using (SSRS, Excel, Power BI, etc), you will get the most flexibility by providing it a standard set of unpivoted data:
declare #t table (id int, TransactionDate date, Outcome varchar(8));
insert into #t values
(1,getdate()-1,'Success')
,(2,getdate()-2,'Success')
,(3,getdate()-2,'Success')
,(4,getdate()-3,'Success')
,(5,getdate()-6,'Failed')
,(6,getdate()-6,'Success')
,(7,getdate()-7,'Success')
,(8,getdate()-8,'Success')
,(9,getdate()-8,'Success')
,(10,getdate()-10,'Success')
,(11,getdate()-10,'Failed')
,(12,getdate()-11,'Success')
,(13,getdate()-13,'Success')
;
with w(ws) as(select dateadd(week, datediff(week,0,getdate())-w, 0) -- Monday at the start of the week, minus w.w weeks for all 12
from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)) as w(w)
)
,d(ws,d) as(select w.ws
,dateadd(day,d.d,w.ws) as d -- Each day that makes up each week for equijoin to Transactions table
from w
cross join (values(0),(1),(2),(3),(4),(5),(6)) as d(d)
)
select d.ws as WeekStart
,t.Outcome
,count(t.TransactionDate) as Transactions
from d
left join #t as t
on d.d = t.TransactionDate
group by d.ws
,t.Outcome
order by d.ws
,t.Outcome;
Output:
+-------------------------+---------+--------------+
| WeekStart | Outcome | Transactions |
+-------------------------+---------+--------------+
| 2018-04-09 00:00:00.000 | NULL | 0 |
| 2018-04-16 00:00:00.000 | NULL | 0 |
| 2018-04-23 00:00:00.000 | NULL | 0 |
| 2018-04-30 00:00:00.000 | NULL | 0 |
| 2018-05-07 00:00:00.000 | NULL | 0 |
| 2018-05-14 00:00:00.000 | NULL | 0 |
| 2018-05-21 00:00:00.000 | NULL | 0 |
| 2018-05-28 00:00:00.000 | NULL | 0 |
| 2018-06-04 00:00:00.000 | NULL | 0 |
| 2018-06-11 00:00:00.000 | NULL | 0 |
| 2018-06-11 00:00:00.000 | Success | 2 |
| 2018-06-18 00:00:00.000 | NULL | 0 |
| 2018-06-18 00:00:00.000 | Failed | 2 |
| 2018-06-18 00:00:00.000 | Success | 5 |
| 2018-06-25 00:00:00.000 | NULL | 0 |
| 2018-06-25 00:00:00.000 | Success | 4 |
+-------------------------+---------+--------------+

SQL Server : query to display new column containing data * factor based on previous record

I am trying to formulate a query in SQL Server where:
Date | Name | Amount | AmountX
------------+---------+--------+-------
2010-01-01 | Test | 0 | 0
2010-02-01 | Test | 0 | 0
2010-03-01 | Test | 0 | 0
2011-01-01 | Test | 62.61 | 63.86
2011-02-01 | Test | 62.61 | 63.86
2011-03-01 | Test | 62.61 | 63.86
2012-01-01 | Test | 62.61 | 65.14
2012-02-01 | Test | 62.61 | 65.14
2012-03-01 | Test | 62.61 | 65.14
2013-01-01 | Test | 62.61 | 66.44
2013-02-01 | Test | 62.61 | 66.44
2013-03-01 | Test | 62.61 | 66.44
2014-01-01 | Test | 62.61 | 67.77
2014-02-01 | Test | 62.61 | 67.77
2014-03-01 | Test | 62.61 | 67.77
2015-01-01 | Test | 0 | 0
2015-02-01 | Test | 0 | 0
2015-03-01 | Test | 0 | 0
2016-01-01 | Test | 67.95 | 69.31
2016-02-01 | Test | 67.95 | 69.31
2016-03-01 | Test | 67.95 | 69.31
2017-01-01 | Test | 67.95 | 70.70
2017-02-01 | Test | 67.95 | 70.70
2017-03-01 | Test | 67.95 | 70.70
2018-01-01 | Test | 67.95 | 72.11
2018-02-01 | Test | 67.95 | 72.11
2018-03-01 | Test | 67.95 | 72.11
2019-01-01 | Test | 67.95 | 73.55
2019-02-01 | Test | 67.95 | 73.55
2019-03-01 | Test | 67.95 | 73.55
The Date, Name and Amount columns come from the table.
I need to create a query to include to AmountX column based on the Date grouping. The Amount and a factor of 2% for calculation.
Year 2010 can be ignored because the Amount values are 0s.
For the year 2011, the Amount values are none 0s which is 62.61. I need to multiply that by 1.02 giving 63.86, for the whole year and display it in the AmountX column.
Now for the year 2012, it will be calculated 63.86 for previous year X 1.02 = 65.14.
So for 2013, it will be 64.14 X 1.02 = 66.44.
And for 2014, it will be 66.44 X 1.02 = 67.77.
Is this doable?
Any help is greatly appreciated.
RS..
I think you want:
select t.*,
(amount * power(1.02, year(date) - 2010)) as amountX
from t;

UPDATE Column value with a count of rows with certain values

Have to update column value with a count of player's rows in table.
Table_Player :
ID | PlayerNr | session_type | Date | CountSes |
------------------------------------------------------------
1 | 1001 | cancelled | 2017-01-01 |
2 | 1001 | ready | 2017-06-06 |
3 | 1002 | ready | 2017-02-02 |
4 | 1002 | ready | 2017-04-04 |
5 | 1003 | waiting | 2017-03-03 |
6 | 1003 | ready | 2017-05-05 |
7 | 1004 | waiting | 2017-10-10 |
8 | 1004 | ready | 2017-11-11 |
9 | 1004 | waiting | 2017-12-12 |
10 | 0 | test | |
I've used :
UPDATE a
SET a.CountSes = b.cnt
FROM Table_Player a
JOIN
(SELECT PlayerNr, COUNT(*) cnt
FROM Table_Player
WHERE PlayerNr <> '0'
GROUP BY PlayerNr)
b ON a.PlayerNr = b.PlayerNr
This does the job but now I need a more detailed count.
Rules are:
session_type = 'waiting' . . Row will be counted only when it's the newest row of player.
PlayerNr = '0' . . . . . . . . . . . Dummy-player's rows will be ignored.
From sample above, the result should be:
ID | PlayerNr | session_type | Date | CountSes |
------------------------------------------------------------
1 | 1001 | cancelled | 2017-01-01 | 2
2 | 1001 | ready | 2017-06-06 | 2
3 | 1002 | ready | 2017-02-02 | 2
4 | 1002 | ready | 2017-04-04 | 2
5 | 1003 | waiting | 2017-03-03 | 1
6 | 1003 | ready | 2017-05-05 | 1
7 | 1004 | waiting | 2017-10-10 | 2
8 | 1004 | ready | 2017-11-11 | 2
9 | 1004 | waiting | 2017-12-12 | 2
10 | 0 | test | |
This goes beyond my knowledge, any Hints ?
Database is SQL Server 2014 SP2.
Thanks for your help.
I have used IIF and Partitioning function ROW_NUMBER to filter ignore waiting rows that are not new and also used SUM instead of COUNT
UPDATE t
SET CountSes = ISNULL(CNT, 0)
FROM Table_Player as t
LEFT JOIN (
SELECT SUM(IIF(session_type = 'waiting'
AND RN > 1, 0, 1)) AS CNT
, PlayerNr
FROM (
SELECT *
, ROW_NUMBER() OVER (
PARTITION BY PlayerNr ORDER BY DATE DESC
) RN
FROM Table_Player
WHERE (PlayerNr <> 0)
) t
GROUP BY PlayerNr
) as p ON p.PlayerNr = t.PlayerNr
rextester demo: http://rextester.com/NBHXYL39648

SQL Server : new column based on other columns

I want to calculate a new value for the new column based on other columns in T-SQL.
My data is look like this:
Each row represents one person in one day.
The WorkHours is calculated based on the Portion column:
Round(FF.Portion * 7.4, 3) AS WorkHours
I want to calculate a percentage of hours which people not have been at work in relation to the TOTAL workhours for day for each school. For example if 10 people work full hour in one school for one day, it gives 74 working hours and if one person have been sick that day it will give (7,4 % 74 * 100) which is 10% (the WorkHours is calculated based on Portion column)
In your comment you state Peter had 6 hours on 1/1/2017 as "seek" but it was actually 7.4. With that in mind, we can calculate your results as follows:
declare #table table (Name varchar(16), Date date, School char(2), FreedayCode int, Freeday varchar(64), Portion decimal (6,4))
insert into #table
values
('Mike','20170101','AA',-1,'AtWork',1),
('Mike','20170201','AA',1,'Seek',1),
('Ali','20170101','BB',-1,'AtWork',0.94594),
('Ali','20170201','BB',-1,'AtWork',0.94594),
('Sara','20170101','CC',2,'holiday',1),
('Sara','20170201','CC',1,'Seek',1),
('Peter','20170101','AA',1,'Seek',1),
('Peter','20170201','AA',1,'Seek',1),
('Nina','20170101','AA',-1,'AtWork',0.81081),
('Nina','20170201','AA',-1,'AtWork',0.81081)
select
Name
,Date
,School
,FreeDayCode
,Freeday,Portion
,NewColumn = sum(case when Freeday <> 'AtWork' then Round(Portion * 7.4,3) else 0 end) over (partition by Date, School) / sum(Round(Portion * 7.4,3)) over (partition by Date, School)
from
#table
order by
Date
,School
RETURNS
+-------+------------+--------+-------------+---------+---------+-----------+
| Name | Date | School | FreeDayCode | Freeday | Portion | NewColumn |
+-------+------------+--------+-------------+---------+---------+-----------+
| Mike | 2017-01-01 | AA | -1 | AtWork | 1.0000 | 0.355769 |
| Peter | 2017-01-01 | AA | 1 | Seek | 1.0000 | 0.355769 |
| Nina | 2017-01-01 | AA | -1 | AtWork | 0.8108 | 0.355769 |
| Ali | 2017-01-01 | BB | -1 | AtWork | 0.9459 | 0.000000 |
| Sara | 2017-01-01 | CC | 2 | holiday | 1.0000 | 1.000000 |
| Peter | 2017-02-01 | AA | 1 | Seek | 1.0000 | 0.711538 |
| Mike | 2017-02-01 | AA | 1 | Seek | 1.0000 | 0.711538 |
| Nina | 2017-02-01 | AA | -1 | AtWork | 0.8108 | 0.711538 |
| Ali | 2017-02-01 | BB | -1 | AtWork | 0.9459 | 0.000000 |
| Sara | 2017-02-01 | CC | 1 | Seek | 1.0000 | 1.000000 |
+-------+------------+--------+-------------+---------+---------+-----------+

pivot and cascade null columns

I have a table that holds values for particular months:
| MFG | DATE | FACTOR |
-----------------------------
| 1 | 2013-01-01 | 1 |
| 2 | 2013-01-01 | 0.8 |
| 2 | 2013-02-01 | 1 |
| 2 | 2013-12-01 | 1.55 |
| 3 | 2013-01-01 | 1 |
| 3 | 2013-04-01 | 1.3 |
| 3 | 2013-05-01 | 1.2 |
| 3 | 2013-06-01 | 1.1 |
| 3 | 2013-07-01 | 1 |
| 4 | 2013-01-01 | 0.9 |
| 4 | 2013-02-01 | 1 |
| 4 | 2013-12-01 | 1.8 |
| 5 | 2013-01-01 | 1.4 |
| 5 | 2013-02-01 | 1 |
| 5 | 2013-10-01 | 1.3 |
| 5 | 2013-11-01 | 1.2 |
| 5 | 2013-12-01 | 1.5 |
What I would like to do is pivot these using a calendar table (already defined):
And finally, cascade the NULL columns to use the previous value.
What I've got so far is a query that will populate the NULLs with the last value for mfg = 3. Each mfg will always have a value for the first of the year. My question is; how do I pivot this and extend to all mfg?
SELECT c.[date],
f.[factor],
Isnull(f.[factor], (SELECT TOP 1 factor
FROM factors
WHERE [date] < c.[date]
AND [factor] IS NOT NULL
AND mfg = 3
ORDER BY [date] DESC)) AS xFactor
FROM (SELECT [date]
FROM calendar
WHERE Datepart(yy, [date]) = 2013
AND Datepart(d, [date]) = 1) c
LEFT JOIN (SELECT [date],
[factor]
FROM factors
WHERE mfg = 3) f
ON f.[date] = c.[date]
Result
| DATE | FACTOR | XFACTOR |
---------------------------------
| 2013-01-01 | 1 | 1 |
| 2013-02-01 | (null) | 1 |
| 2013-03-01 | (null) | 1 |
| 2013-04-01 | 1.3 | 1.3 |
| 2013-05-01 | 1.2 | 1.2 |
| 2013-06-01 | 1.1 | 1.1 |
| 2013-07-01 | 1 | 1 |
| 2013-08-01 | (null) | 1 |
| 2013-09-01 | (null) | 1 |
| 2013-10-01 | (null) | 1 |
| 2013-11-01 | (null) | 1 |
| 2013-12-01 | (null) | 1 |
SQL Fiddle
Don't know if you need the dates to be dynamic from the calender table or if mfg can be more than 5 but this should give you some ideas.
select *
from (
select c.date,
t.mfg,
(
select top 1 f.factor
from factors as f
where f.date <= c.date and
f.mfg = t.mfg and
f.factor is not null
order by f.date desc
) as factor
from calendar as c
cross apply(values(1),(2),(3),(4),(5)) as t(mfg)
) as t
pivot (
max(t.factor) for t.date in ([20130101], [20130201], [20130301],
[20130401], [20130501], [20130601],
[20130701], [20130801], [20130901],
[20131001], [20131101], [20131201])
) as P
SQL Fiddle

Resources