How to compare timestamp in sql server - sql-server

Given the following table, how can I select the most recent timestamp from a given user?
Here is my table:
For instance, if USERID 5, I want to compare every USERID 5 timestamp and return the most recent timestamp.

If you want the latest timestamp for a user you can use the max function:
select userid, max(checktime)
from your_table
group by userid
where userid = 5
If you remove the where clause you'll get a list of all userid with their latest checktime.

Not sure if I understand correctly?
Maybe it is just as simple as that?
SELECT MAX(CHECKTIME) FROM Table WHERE UserID = 5
If not, you could google for OVER clause.

Related

SQL - Insert multiple records from select

I have been searching all day but could not find answer to this:
I have a table on SQL Server:
dbo.Program
with fields:
Program.id...PK autoincrement
Program.user...varchar
Program.program...varchar
Program.installed...boolean
Program.department...varchar
Program.wheninstalled...date
Now, I want to insert a new record for every distinct user and copy the department from his latest(Program.wheninstalled) record with other values the same for every user:
Program.user...every unique user
Program.program...MyMostAwesomeProgram
Program.installed...false
Program.department...department of the record with the latest program.wheninstalled field of all the records of the unique user in program.user
Program.wheninstalled...null
I know how to do it in an ugly way:
select the latest records for every user and their department in that record
extract values from 1) and make it into insert into
(field1, field2...fieldX) values
(1records_value1, 1records_value2...1records_valueX),
(2records_value1, 2records_value2...2records_valueX),
...
(Nrecords_value1, Nrecords_value2...Nrecords_valueX)
but I would like to know how to do it in a better way. Oh I cannot use some proper HR databse to make my life easier so this is what I got to work with now.
I'm a postgres guy, but something akin to the below should work:
insert into Program (user, program, installed, department, wheninstalled)
select user,
'MyMostAwesomeProgram',
false,
(select department from someTable where u.user = ...),
null
from users as u;
from https://stackoverflow.com/a/23905173/3430807
you said you know how to do the select
insert into Program (user, program, installed, department, wheninstalled)
select user, 'MyMostAwesomeProgram', 'false' , department, null
from ...
This should do it:
insert into Program (user, program, installed, department, whenInstalled)
select user, program, installed, department, whenInstalled
from
(
select User
, 'MyMostAwesomeProgram' program
, 0 installed
, department
, null whenInstalled
, row_number() over (partition by user order by whenInstalled desc, id desc) r
from Program
) p
where p.r = 1
The interesting bit is the row_number() over (partition by user order by whenInstalled desc, id desc) r.
This says to return a column, r, which holds values 1..n for each user, counting up according to the order by clause (i.e. starting with the most recent whenInstalled and working backwards).
I also included the id field in the order by clause in case there were two installs for the same user on the same date; in such a case the most recently added (the one with the higher id is used first).
We then put this in a subquery, and select only the first record; thus we have 1 record per user, and it's the most recent.
The only values we use from this record are the user and department fields; all else is defined per your defaults.
So I am gonna answer this for some other people who might google this:
To get a records from a table to another table you need to use Select into statement
I like using With XXX as ( some select) to specify, say, "virtual" table with which you can work during the query
As JohnLBevan meantioned a very useful function Row_number, over, partition by and what i missed is a rank
So once you read on these you should be able to understand how to do what I wanted to do.

How to get the following output using SQL SERVER 2008

I need to implement a logic where I need to get the latest group data from a table .
Here is the example.
Result Date
PASS 6/1/2016
PASS 6/2/2016
FAIL 6/10/2016
FAIL 6/11/2016
PASS 6/20/2016
PASS 6/21/2016
FAIL 7/1/2016
FAIL 7/5/2016
PASS 7/10/2016
PASS 7/11/2016
Required output
ID Result Date
PASS 7/10/2016
PASS 7/11/2016
Can you please help me?
SELECT
ID,
RESULT,
MAX(Date) as Date
FROM Table
GROUP BY ID, RESULT
The solution returns a single row for each ID and RESULT combination as noted by the GROUP BY clause. The row that is returned is the one which has the MAX date, aka the most current date even if it's in the future, with this pairing or grouping.
SELECT * FROM *table_name* WHERE ID IN (9, 10)

Checking existance of dynamic value before update/insert

I am trying to mass update a table column with values but I need to get the query to check whether this value already exists. If it does then to make the relevant changes before checking again and updating the table.
The database primarily holds staff information and I need to create a unique username, the script to create the username is :
select upper(LEFT(first_name,1))+LEFT(surname,3)+'1'
from staff_test
If this was used for an example user it would generate a username of ABit1 for user Andrew Bithell. What I need it to do is check to see if there already is a ABit1 username in the STAFF_TEST table and if so change Andrews username to ABit2 as the usernames have to be unique before it moves onto the next user.
I have created another table which lists all the current usernames splitting the existing usernames into 2 columns, so they display in this table as
column1 | column2
------------------
ABit |1
I have experimented with a function and I am now thinking a Merge statement might be the way to go.
Any suggestions are welcomed.
Use row_number can generate all the unique names at once:
select
upper(LEFT(first_name,1))+LEFT(surname,3)+
rtrim(row_number() over (partition by upper(LEFT(first_name,1))+LEFT(surname,3) ))
,first_name
,surname
from staff_test
Perform an up front check to see if there are any clashes:
SELECT UPPER(LEFT(first_name, 1)) + LEFT(surname, 3) + '1' AS username ,
COUNT(1) counter
FROM staff_test
GROUP BY UPPER(LEFT(first_name, 1)) + LEFT(surname, 3) + '1'
HAVING COUNT(1) > 1
ORDER BY COUNT(1) DESC
This will return each username on your staff table, grouped by the username, along with a count of how many occurrences there are of each.
You can either sanitize the data if that's what you're looking to do, otherwise I would suggest, appending an Id column value or some other unique value per record instead of 1 on the end.

SOQL query WHERE Date = 30_days_ago?

How do I make a SOQL query like this?
SELECT id FROM Account WHERE LastActivityDate = 30_DAYS_AGO
This produces an error:
MALFORMED_QUERY:
Account WHERE LastActivityDate = 30_DAYS_AGO
^
SELECT id FROM Account WHERE LastActivityDate = LAST_N_DAYS:30
As you're doing this from apex, you can calculate the date in apex, then bind that into your query, e.g.
date d = system.today().addDays(-30);
Account [] acc= [select id from account where createdDate = :d];
Select Id from Account Where LastActivityDate = N_DAYS_AGO:30
LAST_WEEK and LAST_MONTH are also easy and work well.
SELECT id FROM Account WHERE LastActivityDate > LAST_MONTH
For more data look at this link: http://www.salesforce.com/us/developer/docs/officetoolkit/Content/sforce_api_calls_soql_select_dateformats.htm
The page of SOQL date functions appears to have moved here: https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm
To clarify, SOQL allows a date field (e.g. LastActivityDate) to be compared against a range of dates using a comparison operator. So "LastActivityDate = LAST_MONTH" is equivalent to saying that the date is greater than or equal to the start of the first day of the previous month AND less than or equal to the end of the last day.
Since it is 30 days ago, you an use this -
SELECT ID FROM Account WHERE LastActivityDate < LAST_N_DAYS:30
Your query time period lies in the Date literals provided SFDC its best to use
it as the time specified is a broad number , , you just need to provide the no of days and accordingly use the operator which is '=' ,'>' or '<'
LAST_N_DAYS:n LAST_N_WEEKS:n LAST_N_MONTHS:n LAST_N_YEAR:n
NEXT_N_DAYS:n NEXT_N_WEEKS:n NEXT_N_MONTHS:n NEXT_N_YEAR:n
your query would look simpler if you just provided the no of days / month which
it falls in .
SELECT id FROM Account WHERE LastActivityDate = LAST_N_MONTHS:1
or
SELECT id FROM Account WHERE LastActivityDate = LAST_N_DAYS:30
Thanks,
OQ.

How do i find the total number of records created on a given day using T-SQL?

I need to find out the total number of records that were created on a given day.
e.g.
ID CreatedDate
1 17/07/2009
2 12/07/2009
3 17/07/2009
4 05/07/2009
5 12/07/2009
6 17/07/2009
Output:
3 Records were created on 17/07/2009
2 Records were created on 12/07/2009
1 Record was created on 05/07/2009
EDIT
Upon testing the second suggestion made by Chris Roberts of including the formatting in the SQL i get this error:
Syntax error converting the varchar value ' Records were created on ' to a column of data type int.
Does anyone know how to rework the solution so that it works?
You should be able to get the data you're after with the following SQL...
SELECT COUNT(ID), CreatedDate
FROM MyTable
GROUP BY CreatedDate
Or - if you want to do the formatting in the SQL, too...
SELECT CONVERT(varchar, COUNT(ID)) + ' Records were created on ' + CONVERT(varchar, CreatedDate)
FROM MyTable
GROUP BY CreatedDate
Good luck!
Is the column actually a timestamp? In which case you will need to apply a function to remove the time component, e.g.:
SELECT COUNT(*), date(CreatedDate) FROM MyTable GROUP BY date(CreatedDate)
I don't know what the function is in T-SQL, it's date() in MySQL and trunc() in Oracle. You may even have to do a to_string and remove the end of the string and group by that if you lack this.
Hope this helps.
select count(*), CreatedDate from table group by CreatedDate order by count(*) DESC

Resources