How can I get count of rows for every week? - sql-server

I have select from table like:
SELECT DATEPART(WEEK, DayTime) as WeekNumber FROM dbo.Transactions
Result:
WeekNumber
1
1
1
2
2
3
4
4
5
4
5
3
How can I get count of rows for every number of week?
I need something like this:
WeekNumber CountOfRows
1 3
2 2
3 2
4 3
5 1

You need to GROUP BY week number and use COUNT function
SELECT DATEPART(WEEK, DayTime), COUNT(*)
FROM dbo.Transactions
GROUP BY DATEPART(WEEK, DayTime)

SELECT DATEPART(WEEK, DayTime) as WeekNumber, COUNT(1) as CountOfRows
FROM dbo.Transactions
GROUP BY WeekNumber;

Related

How get last n month of data for each ID from 2 tables using SQL

I have 2 tables, A and B. I want to have last 3 months of Db_date (table B) from the Start_Date (tableA) for each ID.
Table A
ID
Start_Date
1
2022-08-01
Table B
ID
Start_Date
Amount
1
2022-08-01
1000
1
2022-07-01
2000
1
2022-06-01
3000
1
2022-05-01
500
I know by using below code can get last 3 months from the current moth of Start_Date, but I want have last 3 months of Db_Date Amount from table B, for each Start_Date for each ID in Table A.
SELECT *
FROM TableA
WHERE Start_Date >= DATEADD(M, -3, GETDATE())
You could use an outer apply to get the sum of amount the last three months from TableB
SELECT *
FROM TableA a
OUTER APPLY(SELECT SUM(Amount) as SumAmountFor3MonthsAfterStart
FROM TableB
WHERE StartDate > DATEADD(M, -3, a.Start_Date)
) OA
WHERE Start_Date >= DATEADD(M, -3, GETDATE())

Date Comparison of Two Tables in SQL SERVER

I had this Data,
Table One :
EmpID Date Absent
1 01/01/2018 1
1 01/02/2018 1
1 02/05/2018 1
1 03/25/2018 1
1 04/01/2018 0
1 05/02/2018 1
1 06/03/2018 1
Table Two
ID Amount DateEffective
1 5.00 02/06/2018
2 3.00 05/02/2018
3 10.00 06/03/2018
Desired Output
EmpID Month Year Absent Penalty
1 January 2018 2 5.00
1 February 2018 1 5.00
1 March 2018 1 3.00
1 April 2018 0 3.00
1 May 2018 1 13.00
1 June 2018 1 10.00
This is my Code
SELECT { fn MONTHNAME(one.Date) } AS MonthName, YEAR(one.Date) AS Year, SUM(one.Absent) AS Absent,
(
SELECT top 1 two.DailyRate
FROM table_two as two
WHERE EmpID = '1'
AND one.Date <= two.EffectivityDate
)
FROM table_one as one
WHERE EmpID = '1'
GROUP BY { fn MONTHNAME(one.Date) }, MONTH(one.Date), YEAR(one.DTRDate)
ORDER BY Year(one.Date),month(one.Date)
and it shows an error :
Column 'one.Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
please help for this issue...
Thanks
Try this :
SELECT
one.EmpID
,DATENAME(MONTH,one.Date) AS [MonthName]
,YEAR(one.Date) AS [Year]
,SUM(one.Absent) AS [Absent]
,(SELECT top 1 two.Amount
FROM table_two as two
WHERE two.ID = one.EmpID
AND YEAR(two.DateEffective) >= YEAR(one.Date)
AND MONTH(two.DateEffective) >=MONTH(one.Date)
) AS [Penalty]
FROM table_one as one
WHERE
one.EmpID = '1'
GROUP BY one.EmpID,DATENAME(MONTH,one.Date), MONTH(one.Date), YEAR(one.Date)
ORDER BY Year(one.Date),month(one.Date)
From my understanding to do this,
select e.EmpID
,datename(month,e.Date)[month]
,year(e.Date) [year]
,sum(e.Absent) as [Abscount]
,a.Amount
from
empl e left join abs a
on datename(month,e.Date)=DATENAME(month,a.DateEffective)
group by e.EmpID,DATENAME(MONTH,e.Date), MONTH(e.Date), YEAR(e.Date) , a.Amount
order by Abscount desc
Revert me if any clarifications needed...
is this helpful.?
Create Table #TabOne(EmpID int,[Date] Date,[Absent] Bit)
Create Table #TabTwo(ID int,Amount float,DateEffective Date)
Insert into #TabOne
SELECT 1,'01/01/2018',1 Union All
SELECT 1,'01/02/2018',1 Union All
SELECT 1,'02/05/2018',1 Union All
SELECT 1,'03/25/2018',1 Union All
SELECT 1,'04/01/2018',0 Union All
SELECT 1,'05/02/2018',1 Union All
SELECT 1,'06/03/2018',1
Insert into #TabTwo
Select 1,5.00 ,'02/06/2018' Union All
Select 2,3.00 ,'05/02/2018' Union All
Select 3,10.00,'06/03/2018'
;with cte1
As
(
Select One.EmpID,MONTH(one.[Date]) As [mon],YEAR(one.[Date]) As [Year],two.Amount,one.[Absent],
ROW_NUMBER() OVER(partition by One.EmpID,One.[Date] order by DATEDIFF(dd,two.DateEffective,one.[Date]) desc) as rn
from #TabOne one
LEFT JOIN #TabTwo two on one.[Date]<=two.DateEffective
)
Select EmpID,DATENAME(month, DATEADD(month, [mon]-1, CAST('2008-01-01' AS datetime))) As [Month],
[Year],SUM(CASE WHEN [Absent]=0 then 0 ELSE 1 END) As [Absent] ,MAX(Amount) As Penalty
from cte1
where rn=1
Group by EmpID,[Year],[mon]
order by EmpID,[Year],[mon]
Drop Table #TabOne
Drop Table #TabTwo

Get Count All Rows In Select Column

I have table like this
Id | Name | Status
------+------------+--------------
1 example1 3
1 example2 2
2 example3 3
2 example4 1
3 example5 1
4 example6 3
How To Write SELECT That Get To ME Result Like This
Id | Name | Status | Count_All
------+------------+--------------+------------
1 example1 3 6
2 example2 2 6
3 example3 3 6
4 example4 1 6
5 example5 1 6
6 example6 3 6
The Value Of Column Count_All, Is Count All Rows
Please use this solution..
SELECT Id , [Name] , [Status], COUNT(*) OVER() Count_All
FROM yourTableName
If I am understanding you correctly, you want a count of all rows in the table as the column Count_All, so Add a Count on column id to get all rows as a new column named Count_All then Group by your other columns to allow for the aggregate Count method.
SELECT [Id], [Name], [Status], COUNT([Id]) AS [Count_All]
FROM [dbo].[YourTable]
GROUP BY [Id], [Name], [Status]
This will do it:
SELECT
y.ID,
y.Name,
y.Status,
Count_All = (SELECT COUNT(*) FROM yourtable)
FROM
yourtable AS y
SELECT *,COUNT(1) OVER() AS COUNT FROM TABLE

writing a query and giving a score

I am trying to write a query for the following:
Count the number of transactions in the previous 90 days. Note: This needs to
be averaged out for new members = (No of transactions / Days being a
member) x 90
New members are the one whose DateCreated is between 0 and 90 days from todays date.
Table structure:
Column Name Datatype
---------------------------------
Member_No nvarchar(255)
Order_No int
Transaction_Date datetime
Net money
Date_Created datetime
Also, the final step is after counting the transactions, I need to give a score. So if a member has count more than 8 then give a score of 5.
Following are the ranges:`
Transaction count Score
>8 5
6-8 4
4-6 3
2-4 2
0-2 1
Let me know if any queries
Hope the below code works for you (Not tested because not having Schema.)
;WITH RANKS AS
(
SELECT 0 AS FROM_TR, 2 AS TO_TR, 1 AS SCORE
UNION ALL
SELECT 3 AS FROM_TR, 4 AS TO_TR, 2 AS SCORE
UNION ALL
SELECT 5 AS FROM_TR, 6 AS TO_TR, 3 AS SCORE
UNION ALL
SELECT 7 AS FROM_TR, 8 AS TO_TR, 4 AS SCORE
UNION ALL
SELECT 9 AS FROM_TR, NULL AS TO_TR, 5 AS SCORE
)
, MEMBER_TRANS AS (
SELECT Member_No AS MEMBER_NO
,Date_Created AS DATE_CREATED
,COUNT(DISTINCT Order_No) ACTUAL_TRANSACT_COUNT
,CASE
WHEN Date_Created BETWEEN DATEADD(DD, - 90, GETDATE())
AND GETDATE()
THEN CAST(
COUNT(DISTINCT Order_No) / DATEDIFF(DD, Date_Created, GETDATE()) * 90
AS INT)
ELSE COUNT(DISTINCT Order_No)
END AS TRANSACT_COUNT
FROM TABLE1
WHERE Transaction_Date BETWEEN DATEADD(DD, - 90, GETDATE())
AND GETDATE()
GROUP BY Member_No
,Date_Created
)
SELECT MT.Member_No,MT.TRANSACT_COUNT, R.SCORE FROM MEMBER_TRANS MT
INNER JOIN RANKS R ON MT.TRANSACT_COUNT BETWEEN R.FROM_TR
AND isnull(R.TO_TR,MT.TRANSACT_COUNT)
--Added Extra below code from your comments
UNION ALL
SELECT Member_No,COUNT(DISTINCT Order_No), 1 AS SCORE FROM TABLE1
WHERE Transaction_Date < DATEADD(DD, - 90, GETDATE())
AND Transaction_Date NOT BETWEEN DATEADD(DD, - 90, GETDATE())
AND GETDATE()
GROUP BY Member_No
The code will return the desired result as per your requirement.Please find the snapshot of output for below query.
WITH Mycte
AS
(
Select Member_No,Case when DateDiff(dd,Date_Created,Getdate())>90 then 0 else 1 END AS New_Member
, DateDiff(dd,Date_Created,Getdate()) AS DaysAsMember
,Count(Order_No) TransactionCount from #Sample1
group by Member_No,Date_Created
)
Select Member_No,Case when TransactionCount > 8 THEN 5
WHEN TransactionCount BETWEEN 6 AND 8 THEN 4
WHEN TransactionCount BETWEEN 4 AND 5 THEN 3
WHEN TransactionCount BETWEEN 3 AND 4 THEN 2
WHEN TransactionCount BETWEEN 0 AND 2 THEN 1
END
AS Score
From Mycte

Select element show up in the next 2 month. SQL SERVER

This is a result of a SELECT query of mine.
Code Name MONTH
------- ------------ -----------
Cust3 CustName3 1
Cust2 CustName2 2
Cust5 CustName5 3
Cust2 CustName2 5
Cust2 CustName2 6
Cust3 CustName3 7
Cust6 CustName6 8
Cust1 CustName1 10
Cust1 CustName1 11
Cust3 CustName3 12
Now I want to select rows that have the same Code value for two consecutive months, for example Cust2 is contiguous in months 5 and 6 and Cust1 is contiguous in months 10 and 11:
Code Name MONTH
------- ------------ -----------
Cust2 CustName2 5
Cust2 CustName2 6
Cust1 CustName1 10
Cust1 CustName1 11
Here is another approach using ROW_NUMBER and COUNT() OVER:
SQL Fiddle
WITH Cte AS(
SELECT *,
RN = [Month] - ROW_NUMBER() OVER(PARTITION BY Code ORDER BY [Month])
FROM TestData
),
Cte2 AS(
SELECT *,
CC = COUNT(*) OVER(PARTITION BY Code, RN)
FROM Cte
)
SELECT
Code, Name, [Month]
FROM Cte2
WHERE CC >= 2
I assume the underlying table is denormalized and has this schema:
Code varchar(n),
Name nvarchar(n),
Month int
...and that there is only 1 row for each month.
We can use the LAG function in T-SQL to compare neighbour rows. We don't need the optional OVER partition-by clause as it's a single data set group:
SELECT
[Code],
[Month]
FROM
(
SELECT
[Code],
LAG( [Code], 1 ) AS LastCode
[Month],
LAG( [Month], 1 ) AS LastMonth
FROM
[sourceTable]
ORDER BY
[Month] ASC
) AS Lagged
WHERE
Lagged.[Code] = Lagged.LastCode
AND
Lagged.[Month] = Lagged.LastMonth
The above two answers are pretty neat. Here's another alternative way of solving this (example), perhaps not as elegantly:
select * from
(
-- join to itself, but for month - join to previous month
select a.code, a.month
from test a
inner join test b on a.code=b.code and a.month = b.month-1
union all
-- join to itself, but for month - join to next month
select a.code, a.month
from test a
inner join test b on a.code=b.code and a.month = b.month+1
) a
order by a.code, a.month

Resources