Latest record for each user number? - sql-server

I did search, but the uniqueness of each question makes it hard for me to "translate" it for my dataset.
I have table A named: CLOGS17
With a sub-set of the data and fields shown:
SERIALNO EVDATE SYSNO AREA USRNO
4 2017-01-01 02:03:48.000 1 4 10
4 2017-01-01 02:09:00.000 1 4 10
4 2017-01-01 02:24:44.997 1 6 10
4 2017-01-01 02:56:50.000 1 2 18
5 2017-08-08 02:03:48.000 1 4 10
5 2017-01-09 02:09:00.000 1 4 10
6 2017-04-03 02:24:44.997 1 6 10
8 2017-05-05 02:56:50.000 1 2 18
My goal is to retrieve all records where the combination of SERIALNO + SYSNO + AREA + USRNO has not been used in the last 30 days (inactive user essentiallY) so I can delete that USRNO.
Desired output from above data would be (newest record for each SERIALNO, SYSNO, AREA, and USRNO distinct combination):
SERIALNO EVDATE SYSNO AREA USRNO
4 2017-01-01 02:09:00.000 1 4 10
4 2017-01-01 02:24:44.997 1 6 10
4 2017-01-01 02:56:50.000 1 2 18
5 2017-08-08 02:03:48.000 1 4 10
6 2017-04-03 02:24:44.997 1 6 10
8 2017-05-05 02:56:50.000 1 2 18
I am then able to get only those within the last 30 days.
Given the table data below ("Table B"), it is a list of all stored users:
SERIALNO CONTID SYSNO AREA USRID
36 001 1 * 1
36 001 1 * 18
36 001 1 * 2
36 001 1 * 29
36 001 1 * 36
36 001 1 1 10
This table contains ALL users in the system.
How can I return all the users from Table B that have not been used for a given CONTID, SYSNO, and AREA?

For the first part of your question it would be as simples as a group by of a select on the desired fields:
SELECT SERIALNO,
SYSNO,
AREA,
USRNO,
MAX(EVDATE)
FROM CLOGS17
GROUP BY SERIALNO,
SYSNO,
AREA,
USRNO
Since you didn't provide enough information about the second part. This query will give you the output you show in your question.
So, to get all users that doesn't meet your 30 days criteria (whatever it are), you just do a left join of you user table with the above query seeking the nulls for the query above, like this:
SELECT *
FROM tableb tb LEFT JOIN
(SELECT SERIALNO,
SYSNO,
AREA,
USRNO,
MAX(EVDATE)
FROM CLOGS17
GROUP BY SERIALNO,
SYSNO,
AREA,
USRNO) a
ON tb.SERIALNO = a.SERIALNO,
AND tb.SYSNO = a.SYSNO
AND tb.USRNO = a.USRNO
WHERE a.AREA is null

Related

Data Format in SQL Server

I have data as below :
Month and then corresponding units sold for 3 different item type
Month Sale1 Sale2 Sale3
1 20
2 12
3 50
1 2
2 17
3 56
1 11
2 35
3 9
I want data to be in below format:
Month Sale1 Sale2 Sale3
1 20 2 11
2 12 17 35
3 50 56 9
Maybe SUM is better then MAX if there can be items from one type across different months:
SELECT [Month]
,SUM(Sale1) AS Sale1
,SUM(Sale2) AS Sale2
,SUM(Sale3) AS Sale3
FROM [table]
GROUP BY [Month]

Get output of multiple Counts in one query

Could you help me how to write a query for the following issue:
There are two tables:
Table persons:
P_id Name BirthDate
1 N1 2016-08-02
2 N2 2015-05-02
3 N3 2013-06-01
4 N4 2014-01-09
Table visited:(p_id is foreign key to table persons)
Id. Visitor_id. P_id. Visit_date
1 10 1 2017-03-05
2 11 2 2017-01-01
3 10 2 2017-02-03
4 12 3 2016-05-07
5 11 4 2016-04-09
6 10 1 2017-04-09
We are going to get the count of visited by each Visitor and also count of visited distinct person on filter on for those person who their age are under 1, between 1 and 2, between 2 and 3 at date of visit_date by each visitor_id.
The results should be like :
Under_one Bet_one_two Bet_two_three
Visitor_id VisitedCount/PersonCount VisitedCount/PersonCount VisitedCount/PersonCount
10 2 1 1 1 0 0
11 0 0 1 1 1 1
12 0 0 0 0 1 1
Between 1 and 2 means the result of subtracting visited_date and birthdate (for example : the result of 2013/03/05 - 2011/06/07) is between 1 and 2 years.
I don't know if I can give you the output laid out exactly as you have specified, but this
SELECT
visited.Visitor_id,
visited.P_id,
Int(([Visit_date]-[BirthDate])/365) AS Age,
Count(persons.P_id) AS NumVisits
FROM persons INNER JOIN visited ON persons.P_id = visited.P_id
GROUP BY
visited.Visitor_id,
visited.P_id,
Int((-[BirthDate]+[Visit_date])/365);
returns
Visitor_id P_id Age NumVisits
10 1 0 2
10 2 1 1
11 2 1 1
11 4 2 1
12 3 2 1

How to pull consecutive months data in sql server even if there is null value

I'm newbie trying to create a SQL query to find how much each Theater has sold the tickets per month during previous year (i.e. for all 12 months). If the collection amount is null or blank I need to produce an output as Zero of any such given month in that year.
I have two tables as below mentioned:
TABLE 1:
Month_Number Year
1 2016
2 2016
3 2016
4 2016
5 2016
6 2016
7 2016
8 2016
9 2016
10 2016
11 2016
12 2016
TABLE 2:
Theater month Amount_In_Thousands
ABC 1 165
ABC 3 70
ABC 4 102
GHI 1 45
GHI 2 70
GHI 3 42
GHI 4 57
ABC 6 122
ABC 7 67
ABC 8 22
ABC 9 80
ABC 11 46
ABC 12 38
You might have noticed for 'ABC' Theater there is 0 or null values for month 2, month 5 and month 10. I am unable to produce these missing months with zero value. I tried with simple left outer join but still the data output row doesn't show with month/year and zero value.
I need to produce the output as below:
OUTPUT
Movie_Theators Month Amount_In_Thounds
ABC 1 165
ABC 2 0 *
ABC 3 70
ABC 4 102
ABC 5 0 *
ABC 6 122
ABC 7 67
ABC 8 22
ABC 9 80
ABC 10 0 *
ABC 11 46
ABC 12 38
GHI 1 45
GHI 2 70
GHI 3 42
GHI 4 57
Can anybody please help me how to write sql script in order to produce the output as shown above. Thank you so much in advance.
You can use a CROSS JOIN between every theater and month-year, and then perform a LEFT JOIN with Table2:
SELECT A.Theater,
B.Month_Number,
B.[Year],
ISNULL(C.Amount_In_Thousands,0) Amount_In_Thousands
FROM ( SELECT DISTINCT Theater
FROM dbo.Table2) A -- or use a dbo.Theater table if you have one
CROSS JOIN dbo.Table1 B
LEFT JOIN dbo.Table2 C
ON A.Theater = C.Theater
AND B.Month_Number = C.[month]
AND B.[Year] = C.[Year];

Reset a sum in a query when a date field changes month

I am currently executing the following query:
Select *, Balance = SUM(DailyReAdmits)
OVER (ORDER BY Date_Total ROWS UNBOUNDED PRECEDING)
From #AllReadmits
Which returns these results:
Date_Total DailyReAdmits Balance
2015-08-25 4 4
2015-08-26 8 12
2015-08-27 9 21
2015-08-28 3 24
2015-08-29 1 25
2015-08-30 4 29
2015-08-31 3 32
2015-09-01 5 37
However, when a new month starts, I would like the balance to start over again and look like this:
Date_Total DailyReAdmits Balance
2015-08-25 4 4
2015-08-26 8 12
2015-08-27 9 21
2015-08-28 3 24
2015-08-29 1 25
2015-08-30 4 29
2015-08-31 3 32
2015-09-01 5 5
How can I achieve this?
I supposed that you want partition by month, so try this:
SELECT *, Balance = SUM(DailyReAdmits)
OVER (PARTITION BY DATEPART(MM,Date_Total) ORDER BY Date_Total ROWS UNBOUNDED PRECEDING)
FROM #AllReadmits

SQL Server - Updating multiple records joining with same table

I have a table price_info that contains the following columns:
group_id (int)
product_id (int)
date (datetime)
price_override (money, nullable)
Some sample values:
group_id product_id date price_override
1 1 2014-02-10 25
1 1 2014-02-11 30
1 1 2014-02-12 NULL
1 2 2014-02-10 40
1 2 2014-02-11 40
1 2 2014-02-12 40
1 3 2014-02-10 NULL
1 3 2014-02-11 NULL
1 3 2014-02-12 NULL
2 1 2014-02-10 42
2 1 2014-02-11 52
2 1 2014-02-12 70
2 2 2014-02-10 28
2 2 2014-02-11 87
2 2 2014-02-12 96
2 3 2014-02-10 45
2 3 2014-02-11 89
2 3 2014-02-12 NULL
What I want to do is I want to update the price_override (and apply some calculations) of a product_id where the group_id and date are the same and the price_override is not null.
The calculation I want to do is multiply it by #ratio (float) and add #offset (float)
For example, for group_id 1, product_id 3, I want to set it's price_override to be the (price_override * #ratio) + #offset of group_id 1, product_id 2 (where its price_override is not null).
I've tried searching, but so far everything I've found is based on updating only 1 row using unique ids.
As per the requested edit, to update a single row given the values would be the following:
update price_info set price_override = #value where group_id = #group_id and product_id = #product_id and date = #date
If I understand your question correctly,
update price_info
set price_override = ((price_override * #ratio) + #offset)
where (group_id = 1) and ([DATE] = '2/10/14') and (price_override is not null)
might do what you want.

Resources