How to get new clients by months in SQL Server - sql-server

I have a table Clients.
Every client has da_reg (date registered in our system). I need to make a report:
By months - total number of clients (count(distinct customernumber)); and new customers by da_reg date (I can do this per month like insert all clients from past month into temp table and then compare WHERE da_reg < 'date' and customerid not in (select customerid from #temp) - however it takes a lot of time to every time compare).
How to make it easiest way? In 1-2 steps?
Please help!
Thanks in advance!

please try this
select count(*) as new_count,
month(da_reg) as month,year(da_reg) as year
(select count(*) from tbl a where tbl.da_reg>=a.da_reg) as total_cus
from tbl
group by month(da_reg),year(da_reg)

You can Select DAtE_TIME column by month and then calc an number of row :Example for August
SELECT *,count(a.id)
FROM TABLE A as a
WHERE DATEPART(month, MY_DATETIME) = 8
where a.id PK of A

Related

Query for date groupings?

I have a Client table with basic demographics in rows and a date of birth row (DOB) with a DATE data type.
I'm trying to make a query that will take my entries and count how many clients are between the ages of 18-60, 61-79, 80+. I'm not sure if I'm having a brain-fart, but I can't figure out how to gather that info from my table...
So what I have is:
Last Name First Name DOB
Stein Ethel 1954-01-20
Frank Sam 1981-05-65
etc...
What I want to have is:
Ages 18-60
6
Ages 61-79
10
Ages 80+
20
Any recommendations to proceed?
Using #Alex's suggestion
declare #today datetime
set #today =getdate()
select
s as [start],
e as [end],
count(1) as [count]
from Client join
(values (0,17),(18,60),(61,79),(80,9999)) as ranges(s,e)
on datediff(yy,dob,#today) between s and e
-- where buildingid=1
group by s,e
See demo here

T-SQL find all records in a group with a max last modified date beyond a specific threshold

I have a Database table that has all the information I need arranged like so:
Inventory_ID | Dealer_ID | LastModifiedDate
Each Dealer_ID is attached to multiple Inventory_ID's. What I need is a query that calculates the Max Value LastModifiedDate for each dealer ID and then gives me a list of all the Dealer_ID's that have a last modified date beyond the last 30 days.
Getting The max last modified date for each Dealer_ID is simple, of course:
Select Dealer_ID, Max(LastModifiedDate)as MostRecentUpdate
from Inventory group by Dealer_ID order by MAX(LastModifiedDate)
The condition for records older than 30 day is also fairly simple:
LastModifiedDate < getdate() - 30
Somehow, I just can't figure out a way to combine the two that works properly.
Use HAVING:
Select Dealer_ID, Max(LastModifiedDate)as MostRecentUpdate
from Inventory
group by Dealer_ID
having LastModifiedDate < getdate() - 30
order by MAX(LastModifiedDate)
Check this query:
Select DT.DealerID, DT.MostRecentUpdate
(Select DealerID, Max(LastModifiedDate)as MostRecentUpdate
From YourTable
Group BY DealerID) DT
where DT.MostRecentUpdate < GETDATE() - 30

SQL Server Group data by week but show the start of the week

I have a query to select customer data and I want to keep an evolution of the number of customers. In week 1 I have 2 new customers so the number is 2. In week 2 I receive 3 new customers, so the number of customers is 5.
I have following query to do this
SELECT LAST_UPDATED_WEEK, SUM( NUM_CUSTOMERS ) OVER ( ORDER BY LAST_UPDATED_WEEK ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS "Number of customers"
FROM (
SELECT DATEADD(dd,DATEDIFF(dd,0,REGISTRATION_DATE),0) AS LAST_UPDATED_WEEK,
COUNT(DISTINCT CUSTOMER_ID) AS NUM_CUSTOMERS
FROM CUSTOMERS_TABLE
GROUP BY DATEADD(dd,DATEDIFF(dd,0,REGISTRATION_DATE),0)) AS T
But when I run this query, it doesn't group my data by week. I read about a DATEPART function, but that returns an integer, but I need to have the actual date.
Can someone help me?
Just replace dd in DATEADD and DATEDIFF functions with WEEK

how to calculate all previous datas sum of a sql column on a date range report

I have a crystal report with debit credit columns using a sql command. This report contains a date to date filtering parameters. So the problem is if i filter the report to date range i need all the previous data sum using a sql command.
Select SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
from sum_balance
where sum_date < sum_date
this is my code but i can't get the result from it. (e.g. : if the report starting from 2014-07-01 then i need the sum(debit - credit) of all previous data before 2014-07-01). Can anyone help me to find a solution for this. THe main thing is to add a brought forward balance using sql command on first row. If it is null then it should be 0.00.
Here is your sample table
CREATE TABLE #TEMP(DEBIT NUMERIC(20,2),CREDIT NUMERIC(20,2),DT VARCHAR(20))
INSERT INTO #TEMP
SELECT 1000 DEBIT,500 CREDIT,'2014-11-27' DT
UNION ALL
SELECT 2000 DEBIT,700 CREDIT,'2014-11-28' DT
UNION ALL
SELECT 3000 DEBIT,900 CREDIT,'2014-11-29' DT
I am updating answer for your updated requirement
QUERY 1
This will bring the total till current date, ie, for 2014-11-28 the amount will be (1000+2000)-(500+700), for 2014-11-29 the amount will be (1000+2000+3000)-(500+700+900)
SELECT T2.DEBIT,T2.CREDIT,T2.sum_date,
(SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE))
AMOUNT
FROM sum_balance T2
SQL FIDDLE
QUERY 2
This will bring the sum till previous day, that will be opening balance for today's date ie, for 2014-11-29 the amount will be (1000+2000)-(500+700). For easy understanding I have added the previous column also.
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY CAST(T2.sum_date AS DATE))RNO,
T2.DEBIT,T2.CREDIT,T2.sum_date,
ISNULL((SELECT SUM(DEBIT)-SUM(CREDIT) FROM sum_balance WHERE sum_date <= CAST(T2.sum_date AS DATE)),0)
AMOUNT
FROM sum_balance T2
)
SELECT C1.*,ISNULL(C2.AMOUNT,0) CARRYFORWARD
FROM CTE C1
LEFT JOIN CTE C2 ON C1.RNO=C2.RNO+1
SQL FIDDLE
You can use QUERY 2 and you will get opening balance till previous day in CARRYFORWARD column.
Please leave a message or comment for any changes.
When you need records previous than some date then you need to have that comparision date so that records can be extracted.
Your where clause where sum_date < sum_date won't work this way either you change the right side comparision operator in query or create a parameter in crystal so that user can enter the required end date during run time.
option 1:
E.g: where sum_date < currentdate
option 2:
Create a parameter and declare it in Record Selection Formula in crystal reports so that formed query will be something like
where sum_date < 2014-07-01
You can try this:-
SELECT SUM(CAST(debit as DECIMAL(9,2)))- SUM(CAST(credit as DECIMAL(9,2)))
FROM sum_balance
WHERE sum_date < (Select Max(sum_date) FROM sum_balance)

Count number of 'overlapping' rows in SQL Server

I've been asked to look at a database that records user login and logout activity - there's a column for login time and then another column to record logout, both in OLE format. I need to pull together some information about user concurrency - i.e. how many users were logged in at the same time each day.
Do anyone know how to do this in SQL? I don't really need to know the detail, just the count per day.
Thanks in advance.
Easiest way is to make a times_table from an auxiliary numbers table (by adding from 0 to 24 * 60 minutes to the base time) to get every time in a certain 24-hour period:
SELECT MAX(simul) FROM (
SELECT test_time
,COUNT(*) AS simul
FROM your_login_table
INNER JOIN times_table -- a table/view/subquery of all times during the day
ON your_login_table.login_time <= times_table.test_time AND times_table.test_time <= your_login_table.logout_time
GROUP BY test_time
) AS simul_users (test_time, simul)
I think this will work.
Select C.Day, Max(C.Concurrency) as MostConcurrentUsersByDay
FROM
(
SELECT convert(varchar(10),L1.StartTime,101) as day, count(*) as Concurrency
FROM login_table L1
INNER JOIN login_table L2
ON (L2.StartTime>=L1.StartTime AND L2.StartTime<=L1.EndTime) OR
(L2.EndTime>=L1.StartTime AND L2.EndTime<=L1.EndTime)
WHERE (L1.EndTime is not null) and L2.EndTime Is not null) AND (L1.ID<>L2.ID)
GROUP BY convert(varchar(10),L1.StartTime,101)
) as C
Group BY C.Day
Unchecked... but lose date values, count time between, use "end of day" for still logged in.
This assumes "logintime" is a date and a time. If not, the derived table can be removed (Still need ISNULL though). of course, SQL Server 2008 has "time" to make this easier too.
SELECT
COUNT(*)
FROM
(
SELECT
DATEADD(day, DATEDIFF(day, logintime, 0), logintime) AS inTimeOnly,
ISNULL(DATEADD(day, DATEDIFF(day, logouttime, 0), logintime), '1900-01-01 23:59:59.997') AS outTimeOnly
FROM
mytable
) foo
WHERE
inTimeOnly >= #TheTimeOnly AND outTimeOnly <= #TheTimeOnly

Resources