Here is a T-SQL query:
SELECT
A.DateStamp,
CASE WHEN A.T = 10 THEN A.counts END AS HT,
CASE WHEN A.T = 98 THEN A.counts END AS BP,
CASE WHEN A.T = 94 THEN A.counts END AS MP,
CASE WHEN A.T = 12 THEN A.counts END AS SP
FROM
A
WHERE
(A.date_time BETWEEN GETDATE() - 60 AND GETDATE() - 30) -- say
--GROUP BY A.DateStamp,A.T,A.counts
ORDER BY
CONVERT(DATE, A.DateStamp) ASC
It works well. Previously I was using multiple copies of table A and all joined. over here results are correct but split in multiple rows like:
date | BP | MP | SP | HT |
-----------+----+----+----+----+
22/10/2017 12 34 56 78
Looks Like -- -- -- --
22/10/2017 12 -- -- --
22/10/2017 -- 34 -- --
22/10/2017 -- -- 56 --
22/10/2017 -- -- -- 78
You need to use conditional aggregation for this and GROUP BY just the DateStamp field:
SELECT A.DateStamp,
SUM(CASE WHEN A.T=10 THEN A.counts ELSE 0 END) AS HT,
SUM(CASE WHEN A.T=98 THEN A.counts ELSE 0 END) AS BP,
SUM(CASE WHEN A.T=94 THEN A.counts ELSE 0 END) AS MP,
SUM(CASE WHEN A.T=12 THEN A.counts ELSE 0 END) AS SP
FROM A
WHERE (A.date_time BETWEEN getdate()-60 AND getdate()-30)
GROUP BY A.DateStamp
ORDER BY convert(date,A.DateStamp) ASC
i guess you need to group by date only
SELECT convert(date,A.DateStamp) AS Date,
SUM(CASE WHEN A.T=10 THEN A.counts END) AS HT ,
SUM(CASE WHEN A.T=98 THEN A.counts END) AS BP,
SUM(CASE WHEN A.T=94 THEN A.counts END) AS MP,
SUM(CASE WHEN A.T=12 THEN A.counts END) AS SP
FROM A
WHERE A.date_time BETWEEN getdate()-60 AND getdate()-30
GROUP BY convert(date,A.DateStamp)
ORDER BY convert(date,A.DateStamp) ASC
I have a query that I have been using to track users sales. Previously they ere required to make a quota each month. Now, however they would like to change the rule to allow them to start any month, so they may go from June to June or whatever. they also want users to start over immediately if they miss a month. This does seem to be a more equitable system because if they didn't make the quota in March, for example, they were unable to count any they made after that month for the entire year. This really messes up my query though, and I don't know how to fix it. anyone have a solution?
here is the existing t-sql.
#Year int
AS
BEGIN
DECLARE #DateStart datetime
DECLARE #DateStop datetime
SELECT #DateStart = CONVERT(DATETIME, CONVERT( char(4), #Year) + '-01- 01')
SELECT #DateStop = CONVERT(DATETIME, CONVERT( char(4), #Year + 1) + '-01- 01')
SET NOCOUNT ON;
SELECT r.riderid,
r.dname,
DATEPART(yyyy, m.ridedate),
SUM(CASE DATEPART(mm, m.datesale) WHEN 1 THEN m.quota ELSE 0 END) AS [jan],
SUM(CASE DATEPART(mm, m.datesale) WHEN 2 THEN m.quota ELSE 0 END) AS [feb],
SUM(CASE DATEPART(mm, m.datesale) WHEN 3 THEN m.quota ELSE 0 END) AS [mar],
SUM(CASE DATEPART(mm, m.datesale) WHEN 4 THEN m.quota ELSE 0 END) AS [apr],
SUM(CASE DATEPART(mm, m.datesale) WHEN 5 THEN m.quota ELSE 0 END) AS [may],
SUM(CASE DATEPART(mm, m.datesale) WHEN 6 THEN m.quota ELSE 0 END) AS [jun],
SUM(CASE DATEPART(mm, m.datesale) WHEN 7 THEN m.quota ELSE 0 END) AS [jul],
SUM(CASE DATEPART(mm, m.datesale) WHEN 8 THEN m.quota ELSE 0 END) AS [aug],
SUM(CASE DATEPART(mm, m.datesale) WHEN 9 THEN m.quota ELSE 0 END) AS [sep],
SUM(CASE DATEPART(mm, m.datesale) WHEN 10 THEN m.quota ELSE 0 END) AS [oct],
SUM(CASE DATEPART(mm, m.datesale) WHEN 11 THEN m.quota ELSE 0 END) AS [nov],
SUM(CASE DATEPART(mm, m.datesale) WHEN 12 THEN m.quota ELSE 0 END) AS [dec],
SUM(m.quota) as [tot]
FROM users u
JOIN mysales m
ON m.riderid = u.riderid
Where m.datesale Between #DateStart AND #DateStop
GROUP BY DATEPART(yyyy, m.datesale), u.userid
ORDER BY DATEPART(yyyy, m.datesale), SUM(m.quota) DESC
END
OK -here is data
The table holds the users id, the customer id , amount of sale and date of sale
The query pulls the user, the sum of sales by month. User 250 made quota in July/2016, but did not in August, so he should get an entry in #quota for July, and September, but because he did not in August he has to restart in September; user# 300 has made quota from Jan 2016 to SEPT so he has qualified for his bonus as long as he finishes the 12 months. User 350 has successfully finished the year and should get a bonus. at this time in prod there is no quota table, would that simplify? What I need is a list of users that are in the running.
--drop table #sales
--drop table #quota
create table #sales
(
--saleid int --PK
userid int -- salesperson FK
, customerid int --FK
, sale_amt decimal
, date_sale datetime
)
insert into #sales values
(300,1301,542.90,'3-2-2016'),
(300,1301,782.70,'3-4-2016'),
(300,1541,600.70,'3-7-2016'),
(300,903,640.71,'3-10-2016'),
(300,1745,900.01,'3-29-2016'),
(300,1440,2040.71,'2-10-2016'),
(300,903,640.71,'2-20-2016'),
(300,414,1489.00,'1-18-2016'),
(300,1645,1322.00,'1-20-2016'),
(300,1200,1156.09,'4-2-2016'),
(300,1204,1456.00,'4-20-2016'),
(250,1140,156.89,'4-12-2016'),
(250,1240,1176.69,'4-14-2016'),
(250,840,480.61,'4-17-2016'),
(250,1940,500.71,'5-17-2016'),
(250,1425,4800.61,'6-1-2016'),
(250,1840,701.32,'6-15-2016'),
(250,1840,701.32,'7-15-2016'),
(250,1840, 2701.32,'8-15-2016'),
(450,8421,2500.61,'7-17-2015'),
(450,8422,2500.1,'8-17-2015'),
(450,843,2500.1,'9-17-2015'),
(450,8431,2500.00,'10-17-2015'),
(450,1431,2500.00,'11-17-2015'),
(450,4311,2500.00,'12-17-2015'),
(450,4310,2500.00,'1-17-2016'),
(450,1310,2500.00,'2-17-2016'),
(450,1310,2500.00,'3-17-2016'),
(450,130,2500.00,'4-17-2016'),
(450,1130,2500.00,'5-17-2016'),
(450,113,2500.00,'6-17-2016')
Select userid
, sum(sale_amt) Sale
, DATEPART(mm,date_sale) as[month]
from #sales
group by userid, DATEPART(mm,date_sale) order by userid
create table #quota
(
qid int --PK
, userid int -- salesperson FK
, quota bit -- awarded when sales => $2500.00
, datesale datetime -- date quota made
)
Just one possible way to write a query that looks back #running_months number of months to verify that no quotas have been missed during the window for each user:
select userid from users u
where not exists (
select 1 from #sales s
where s.userid = u.userid
and date_sale > dateadd(month, -#running_months - 1, current_timestamp)
and datediff(month, sales_date, current_timestamp) between 1 and #running_months
group by month(sales_amt)
having sum(sales_amt) < 2500
)
EDIT: I later realized that you probably do have users with no sales during a month so you'll probably need to actually verify the condition that all the months are over quota rather than none of the months are under quota:
select userid from users u
where userid in (
select userid from
(
select userid from #sales s
where s.userid = u.userid
and date_sale > dateadd(month, -#running_months - 1, current_timestamp)
and datediff(month, sales_date, current_timestamp) between 1 and #running_months
group by month(sales_amt)
having sum(sales_amt) >= 2500
) q
group by userid
having count(*) = #running_months
)
My data is in below format:
employee order id date
a 123 01/06/2013
b 124 02/06/2013
a 125 02/06/2013
a 129 02/06/2013
I need the data in below format:
employee day 1 day 2
a 1 2
b 0 1
Try this one -
DECLARE #temp TABLE
(
dtStart DATETIME
, employees CHAR(1)
)
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('b','02/06/2013')
SELECT
employees
, day1 = COUNT(CASE WHEN DAY(dtStart) = 1 THEN 1 END)
, day2 = COUNT(CASE WHEN DAY(dtStart) = 2 THEN 1 END)
FROM #temp
--WHERE dtStart BETWEEN '01/06/2013' AND '30/06/2013'
GROUP BY employees
Something along these lines should work (depending on whether you have a fixed amount of days or not):
select employee,
SUM(CASE WHEN date = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN date = '02/06/2013' THEN 1 ELSE 0 END) as day2
from table
group by employee
select distinct employees,
SUM(CASE WHEN dtStart = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN dtStart = '02/06/2013' THEN 1 ELSE 0 END) as day2
from yourTable
group by dtStart,employees
see your demo
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
I have a table employees[employee_id,age] and I wish to return the percentage of employees age between 18 and 20, and 26-40, something like:
Age Interval Percent
18-20 35%
26-40 40 %
Thanks
Select t.range as [age interval] , Count(*) as 'number of appereances' from
(Select case when age between 18 and 26 then '18-26'
when age between 26-40 then '26-40' end as range from employees) t
group by t.range
select '18-20',
count(case when age between 18 and 20 then 1 end) * 100.0 / count(*)
from employees
union all
select '26-40',
count(case when age between 26 and 40 then 1 end) * 100.0 / count(*)
from employees
SQL Fiddle Example #1
You could also write a slightly cleaner (easier to maintain) version like this:
select cast(r.Start as varchar(3)) + '-' + cast(r.[End] as varchar(3)),
count(case when e.age between r.Start and r.[End] then 1 end) * 100.0 / (select count(*) from employees)
from (
select 18 as Start, 20 as [End]
union all
select 21 as Start, 25 as [End]
union all
select 26 as Start, 40 as [End]
) r
left outer join employees e on e.age between r.Start and r.[End]
group by cast(r.Start as varchar(3)) + '-' + cast(r.[End] as varchar(3))
SQL Fiddle Example #2
You generally want to do this sort of thing with windows functions:
Select t.range as [age interval] , Count(*) as 'number of appereances',
cast(count(*)*100.0/tot as varchar(256))+'%' as 'percent'
from (Select (case when age between 18 and 26 then '18-26'
when age between 26 and 40 then '26-40'
end) as range,
count(*) over (partition by NULL) as tot
from employees) t
group by t.range
I also formatted the number as you have it in your example.
SELECT
SUM(CASE WHEN [dbo].[GetAge](DateOfBirth) < 20 THEN 1 ELSE 0 END) AS [Under_20],
SUM(CASE WHEN [dbo].[GetAge](DateOfBirth) BETWEEN 20 AND 25 THEN 1 ELSE 0 END) AS [Age_21_25],
SUM(CASE WHEN [dbo].[GetAge](DateOfBirth) >=26 THEN 1 ELSE 0 END) AS [Age_26_Elder]
from AspNetUsers(nolock) au inner join AspNetUserRoles(nolock) aur
on au.Id=aur.UserId inner join AspNetRoles(nolock) ar on aur.RoleId=ar.Id
Inner join StudentProfiles(nolock) st on au.Id = st.UserId
Select
CAST(ROUND(count(case when 18 <= age and age < 26 then 1 end) * 100.0 / count(*),2)AS NUMERIC(8,2)) as '18-26'
,CAST(ROUND(count(case when 26 <= age and age < 40 then 1 end) * 100.0 / count(*),2)AS NUMERIC(8,2)) as '26-40'
From employees
plus obtimisée