Query user logins using distinct and reprot back daily, weekly and monthly usage - sql-server

I have a SQL Query, that I'm looking to report back site usage hourly, daily, weekly and monthly.
I require the query to use Distinct as the nature of the application will create several entries to the table upon a each new login to the site.
Here is what I have so far:
SELECT DISTINCT OPRID,
CONVERT(varchar(12), LOGINDTTM, 112) 'Date'
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
ORDER BY Date
This will give the following:
OPRID LOGIPADDRESS LOGINDTTM LOGOUTDTTM
dadams 10.1.1.5 20130612 20130612
jblake 10.1.1.5 20130614 20130614
First I do need to group the data as mentioned above by day. This is what I'm looking for, for this part:
LOGINDATE-TIME TOTAL-LOGINS
20130612 25
20130613 35
20130614 45

SELECT CONVERT(varchar(12), LOGINDTTM, 112) 'Date', count(*) as TOTAL-LOGINS
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
GROUP BY Date
ORDER BY Date

It is unclear to me how your query results in the table you produce. Your query does not mention logoutdttm. In any case, you can do what you want by grouping by date and counting the distinct "OPRID"s on each date (if I understand your request correctly):
SELECT CONVERT(varchar(12), LOGINDTTM, 112) as "Date", count(distinct OPRID) as NumOPRs
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
group by CONVERT(varchar(12), LOGINDTTM, 112)
ORDER BY Date
(As a side note, SQL Server doesn't allow you to use an alias in the group by column.)
Instead of the convert(), I prefer converting the date time to a date data type:
SELECT cast(LOGINDTTM as date) as "Date", count(distinct OPRID) as NumOPRs
from PSACCESSLOG_HIST
where OPRID NOT IN ('AUTOPROC', 'PSAPPS', 'PHSADBA', 'PTWEBSERVER')
group by cast(LOGINDTTM as date)
ORDER BY "Date"
Also, although SQL Server may allow you to put the aliases for columns in single quotes, you should use double quotes or square brackets. Single quotes have a strong meaning as a constant string in a SQL statement, and not as the name of a column or table.

Related

Creating SQL views in VBA

I am trying to create a view on a table called petients in my database. The table has five columns. One of them is the column which I want to keep patient admitted date. It data type is datetime so I want to create a query that filters the data in this table based on current date. For example I want create a view that shows only details of petients who have been recorded on the current day.
Here is my code:
CREATE VIEW [dbo].[recent petients]
AS
SELECT petient_id, name, age, contact
FROM [petients]
WHERE [date] = 'date.Today'
I am getting an error saying that failed to convert date to string. Can you help me to solve it, or where is my code wrong?
Your code looks like SQL Server code. If so, I would recommend:
SELECT petient_id, name, age, contact
FROM [patients]
WHERE [date] = CONVERT(date, GETDATE());
As a note: This version is much better than DATEDIFF() because it allows the use of an index on patient([date]).
If the "date" column has a time component, you can use:
WHERE CONVERT(date, [date]) = CONVERT(date, GETDATE())
Note that this is also index-safe in SQL Server.
I'm assuming you are using Transact-SQL from Microsoft SQL Server, but you should specify the sql dialect you are using.
Since the datetime field type generally includes also a time, it is better to use the DATEDIFF function: https://learn.microsoft.com/it-it/sql/t-sql/functions/datediff-transact-sql?view=sql-server-ver15
In your case, to consider only the record where date=today, the difference in days must be zero:
--SQL QUERY
WHERE DATEDIFF(day, GETDATE(), [date]) = 0
day identifies the element you want to consider the difference. A list of names or abbreviations can be found in the link
GETDATE() returns now datetime
2nd and 3rd arguments are the dates you want to make the difference between

How to convert varchar into usable date in SQL Server?

I am having an issue converting an nvarchar into a date.
The column title is DOS and the dates are formatted like 05-03-2012.
I am trying to convert to a date so I can filter in the where clause.
I have seen explanations using CONVERT(datetime, DOS, 101) but I am not sure where this would go? In the select? In the where clause? Is this the best method to convert varchar into date?
SELECT BedSize
,avg(contributionmargin) AS ContributionMargin
FROM Summary
WHERE DOS > '06-30-2016'
GROUP BY bedsize
HAVING avg(contributionmargin) > 10000
ORDER BY contributionmargin DESC
In this example the where clause is just looking at the '06' in the date and selecting values that are greater than 06, so the results include:
07/01/2013
07/02/2009
08/31/2009
09/25/2012
11/03/2016
12/03/2008
The problem is that the years are ignored.
Option 1:
Add a new datetime column (let's suppose DOSDate) in the table and then run this query
update mytable set DOSDate = STR_TO_DATE(DOS,'%m-%d-%Y')
But future inserts in mytable will also needs to be converted and stored in DOSDate` column.
Option 2:
If you cannot add a new column, use this in where clause
select * from mytable where STR_TO_DATE(DOS,'%m-%d-%Y') > p_mydate
Since you have not provided a query, the above is a sample query to illustrate the point.
UPDATE
Initially you marked your question related to MySQL. For SQL Server you may use CAST or CONVERT instead of STR_To_DATE https://msdn.microsoft.com/en-us/library/ms187928(v=sql.90).aspx
I was able to use the convert function for SQL Server.
This code works:
SELECT BedSize
,avg(contributionmargin) AS ContributionMargin
FROM Summary
WHERE Convert(DATE, DOS, 101) > '06-30-2016'
GROUP BY bedsize
HAVING avg(contributionmargin) > 10000
ORDER BY contributionmargin DESC

Converting String to Int in SQL Server

I have column Terms in my table and it contains data like this:
30D, 40D, etc.
D represents days.
My question: how can I sum date in Terms column? How can I convert string to int?
Thank you in advance.
Just use REPLACE to ditch the D and CONVERT to convert the varchar to a number....
SELECT SUM(CONVERT(int, REPLACE(Terms,'D',''))) FROM TableName
Edit: Commentor is right, CAST would work too.
And I dont get all the down votes. The guy's just asking a SQL question.
Jeez... Tough crowd.
Edit2:
OK, based on comments, it seems like you would like to get a "due date" from the terms (say, TODAY + 30D or "today + 30 days"). To do that, we'd need a DATE column. OR, we can just use today's date (GETDATE())
Assume your table has a date column called ... dt
The SQL to pull dt+'30D' would require us to add 30 "days" to dt.
DATEADD will add days, and the aforementioned CONVERT+REPLACE combo will convert '30D' to just plain '30' ...
So, you end up with the following SQL:
SELECT DATEADD(day, CONVERT(int, REPLACE(Terms,'D','')), dt) FROM TableName
The 'day' tells DATEADD to add days (that seems really obvious ... now),
the CONVERT+REPLACE tells it how many days to add
AND - dt is our column name.
SO - how about just adding "30D" to TODAY? Easy. We just swap out dt with GETDATE() ...
SELECT DATEADD(day, CONVERT(int, REPLACE(Terms,'D','')), GETDATE()) FROM TableName
SELECT AVG(SALARY) - AVG(CONVERT(int, REPLACE(SALARY,'0','')))
FROM EMPLOYEES;

SQL Server Stored Procedure get nearest available date to parameter

I have a table of database size information. The data is collected daily. However, some days are missed due to various reasons. Additionally we have databases which come and go over or the size does not get recorded for several databases for a day or two. This all leads to very inconsistent data collection regarding dates. I want to construct a SQL procedure which will generate a percentage of change between any two dates (1 week, monthly, quarterly, etc.) for ALL databases The problem is what to do if a chosen date is missing (no rows for that date or no row for one or more databases for that date). What I want to be able to do is get the nearest available date for each database for the two dates (begin and end).
For instance, if database Mydb has these recording dates:
2015-05-03
2015-05-04
2015-05-05
2015-05-08
2015-05-09
2015-05-10
2015-05-11
2015-05-12
2015-05-14
and I want to compare 2015-05-06 with 2015-05-14
The 2015-05-07 date is missing so I would want to use the next available date which is 2015-05-08. Keep in mind, MyOtherDB may only be missing the 2015-05-06 date but have available the 2015-05-07 date. So, for MyOtherDb I would be using 2015-05-07 for my comparison.
Is there a way to proceduralize this with SQL WITHOUT using a CURSOR?
You're thinking too much into this, simple do a "BETWEEN" function in your where clause that takes the two parameters.
In your example, if you perform the query:
SELECT * FROM DATABASE_AUDIT WHERE DATE BETWEEN param1 /*2015-05-06*/ and param2 /*2015-05-14*/
It will give you the desired results.
select (b.dbsize - a.dbsize ) / a.dbsize *100 dbSizecChangePercent from
( select top 1 * from dbAudit where auditDate = (select min(auditDate) from dbAudit where auditDate between '01/01/2015' and '01/07/2015')) a
cross join
(select top 1 * from dbAudit where auditDate = (select max(auditDate) from dbAudit where auditDate between '01/01/2015' and '01/07/2015')) b
The top 1 can be replaced by a group by. This was assuming only 1 db aduit per day

Splitting DateTime into two columns in T-SQL

I have a datetime field (e.g. 2013-07-02 01:14:32.000) that I'm trying to split into two columns with the Alias Column name of "Date Added" and "Time Added:". I would only like to see the results of all the data that consists in the 4 day span prior to the current date. I would also like to cut out the microseconds. Is this an easy fix or not? I'm still learning the ropes of SQL Server Management Studio 2008. Can anyone edit my query to display the correct output?
Existing Query:
Select as_key AS [Key:], as_name AS [Server Name:], as_introdate AS [Date Added:]
from AutomationStations
Order By [Date Added:] desc
Sample Output from Existing Query:
Key: 0001
Server Name: Server1
Date Added: 2013-07-02 01:14:32.000
Or an alternate method casting to Date and Time datatypes..
SELECT
as_key AS 'Key:',
as_name AS 'Server Name:',
CAST(as_introdate AS DATE) 'Date Added:',
CAST(as_introdate AS TIME(0)) AS 'Time Added:'
FROM AutomationStations
WHERE DATEDIFF(DAY,as_introdate,GETDATE()) <= 4
ORDER BY as_introdate DESC
Easiest way it to extract the desired parts from built-in date formats:
SELECT
as_key AS [Key:],
as_name AS [Server Name:],
CONVERT(VARCHAR(10),as_introdate,101) AS [Date Added:],
CONVERT(VARCHAR(8) ,as_introdate,108) AS [Time Added:]
FROM AutomationStations
WHERE DATEDIFF(d,as_introdate,GETDATE()) <= 4
ORDER BY as_introdate DESC
CONVERT(DATE, YOUR_SELECTED_DATETIME) AS DATE,
CONVERT(TIME, YOUR_SELECTED_DATETIME) AS TIME
This way you keep your data types.

Resources