Getting the oldest record - sql

How can I write a SQL Query to get the oldest male age in number format, not in the dob format?
name dob date job sex language prof salary
-------------------------------------------------------------------------
mitesh 1981-01-01 2001-01-01 m java architect 3100.00
ankur 1982-02-02 2001-02-02 m ruby scientist 3200.00
dhruv 1983-03-03 2001-03-03 m csharp designer 3300.00
ruchi 1981-01-01 2002-01-01 f php teacher 4000.00

You could do something like:
Select top (1) Name, dob, datediff(YY,[dob],getdate()) as Age
from dbo.YourTableName
where sex = 'm'
order by Age Desc
Which would work in SSMS

This MySQL query selects the oldest male and converts the 'dbo' format to an age
SELECT MAX(TIMESTAMPDIFF(dob, '1970-02-01', CURDATE())) AS age
FROM dbo.data
WHERE sex='m'

age function
Some database such as Postgres offer an age function to calculate the span of time between a pair of timestamps. Passing a single timestamp means the current date-time will be used as the second of the pair.
Time Zone
You may care about time zone if you want a precise age.
For example, a new days dawns earlier in Paris than in Montréal. So if running SQL code around midnight, you will get a different result if the code runs on a server with a different current default time zone.
If you care about this level of accuracy, specify the second date in the pair. Use a function that takes a time zone to determine today’s date.
String as Date-Time Type
Ideally you should be storing date-time values as date-time types. But I'm guessing that in this Question your date is actually a textual value.
Alphabetical Order = Chronological Order
If that date-of-birth column is a text value in SQL format, parallel to ISO 8601 format, then its alphabetical ordering is also a chronological ordering. So we can directly use such ordering to find the oldest value.
LIMIT To Get First Row
The LIMIT command truncates the result set to the first x number of rows. Sorting by the date of birth in ascending order means we will get the first row only.
Example Code
Tip: Naming columns and other objects in SQL with a trailing underscore avoids absolutely any collision with keywords/reserved words. So promises the SQL spec.
SELECT name_ , date_of_birth_ , age( timestamp date_of_birth_ ) AS age_
WHERE sex_ = 'm'
ORDER BY date_of_birth_ ASC
LIMIT 1
;

Related

Use SQL to ensure I have data for each day of a certain time period

I'm looking to only select one data point from each date in my report. I want to ensure each day is accounted for and has at least one row of information, as we had to do a few different things to move a large data file into our data warehouse (import one large Google Sheet for some data, use Python for daily pulls of some of the other data - want to make sure no date was left out), and this data goes from now through last summer. I could do a COUNT DISTINCT clause to just make sure the number of days between the first data point and yesterday (the latest data point), but I want to verify each day is accounted for. Should mention I am in BigQuery. Also, an example of the created_at style is: 2021-02-09 17:05:44.583 UTC
This is what I have so far:
SELECT FIRST(created_at)
FROM 'large_table'
ORDER BY created_at
**I know FIRST is probably not the best clause for this case, and it's currently acting to grab the very first data point in created_at, but just as a jumping-off point.
You can use aggregation:
select any_value(lt).*
from large_table lt
group by created_at
order by min(created_at);
Note: This assumes that created_at is a date -- or at least only has one value per date. You might need to convert it to a date:
select any_value(lt).*
from large_table lt
group by date(created_at)
order by min(created_at);
BigQuery equivalent of the query in your question
SELECT created_at
FROM 'large_table'
ORDER BY created_at
LIMIT 1

Using group by with date

I have a table containing the following columns:
stats_date (YYYY-MM-DD)
registered (INT)
opened_form (INT)
Compose a query that will return the total registered, and opened_form by month for the last 3 months. Also a calculated column called conversion_rate which is the registered column divided by the opened_form.
Are you just looking for aggregation? Date/time functions differ significantly among databases, but the idea is:
select year(stats_date), month(stats_date),
sum(registered), sum(opened_form),
sum(registered) * 1.0 / sum(opened_form) as ratio
from t
group by year(stats_date), month(stats_date)
order by min(stats_date);
Of course, your database might have a different way of extracting the year and month from a date.
You can see the ANSI SQL at page 187 to understand how agregation works. To know how to group your column by Month you need to check the documentation of your db, usually is MONTH(COLUMN_NAME).

Separate store year , month value in SQL db

insert into Salary (Year, Month, Day, Amount, Deduction, Employee_ID)
values ('2012', '12', '4', '400', '50', '6')
it gives me error
Conversion failed when converting date and/or time from character string.
It is better to store the date in a single column by specifying the datatype date to the column. Saving like this is not efficient.
Use the datatype DATE.
Column name datatype
------------ -------
EmployeeId Int
Salary_Date Date
Amount Double
Please let me know if this is not what you're looking for. Hope this helps :)
You question has been answered in the comments to your request. Make sure to use proper data types and see to it that types match when you access the columns.
However, I'd like to say a word to Year, Month, and Day integers versus one date column:
Usually you would store dates in a date column of course. This is what the data type date is made for. But there are reasons why not do so and rather store dates in separate integer columns.
In your example Month and Day could be nullable. Then you could enter different types of salaries: A salary for a month (year + month given), a special salary for the year (only year given), a salary granted on a certain day, say for a successfully finished project.
In a nutshell: If a part of the date can be null, then use separate integer columns. If not, use a date column.

Is it possible to return part of a field from the last row entered into a table

I am proposing to have a table (the design isn't settled on yet and can be altered dependent upon the views expressed in reply to this question) that will have a primary key of type int (using auto increment) and a field (ReturnPeriod of type Nchar) that will contain data in the form of '06 2013' (representing in this instance June 2013).
I would simply like to return 06 or whatever happens to be in the last record entered in the table. This table will never grow by more than 4 records per annum (so it will never be that big). It also has a column indicating the date that the last entry was created.
That column seems to my mind at least to be the most suitable candidate for getting the last record, so essentially I'd like to know if sql has a inbuilt function for comparing the date the query is run to the nearest match in a column, and to return the first two characters of a field.
So far I have:
Select Mid(ReturnPeriod,1,2) from Returns
Where DateReturnEntered = <and this is where I'm stuck>
What I'm looking for is a where clause that would get me the last entered record using the date the query is run as its reference point(DateRetunEntered of type Date contains the date a record was entered).
Of course there may be an even easier way to guarantee that one has the last record in which case I'm open to suggestions.
Thanks
I think you should store ReturnPeriod as a datetime for example not 06 2013 as a VARCHAR but 01.06.2013 as a DATETIME (first day of 06.2013).
In this case, if I've got your question right, you can use GETDATE() to get current time:
SELECT TOP 1 MONTH(ReturnPeriod)
FROM Returns
WHERE DateReturnEntered<=GETDATE()
ORDER BY DateReturnEntered DESC
If you store ReturnPeriod as a varchar then
SELECT TOP 1 LEFT(ReturnPeriod,2)
FROM Returns
WHERE DateReturnEntered<=GETDATE()
ORDER BY DateReturnEntered DESC
I would store your ReturnPeriod as a date datatype, using a nominal 1st of the month, e.g. 1 Jun 2013, if you don't have the actual date.
This will allow direct comparison against your entered date, with trivial formatting of the return value if required.
Your query would then find the latest date prior to your date entered.
SELECT MONTH(MAX(ReturnPeriod)) AS ReturnMonth
FROM Returns
WHERE ReturnPeriod <= #DateReturnEntered

Date/Time data types and declaration in SQL Server

I would like to have a date and time column in my table. The main purpose of having these 2 columns is to be able to return query results like:
Number of treatments done in the period November 2011.
Number of people working in shifts between 00:01 and 08:00 hours.
I have two tables, which have the following attributes in them(among others):
Shift(day, month, year)
Treatment(start_time, date)
For the first table- Shift, query results need to return values in
terms of (ex: December 30,2012)
For the second table, start_time needs to have values like 0001 and
0800(as I mentioned above). While, date can return values like
'November 2011'.
Initially I thought using the date datatype for declaring each of the day/month/year/date variables would do the job. But this doesn't seem to work out. Should I use int, varchar and int respectively for day, month and year respectively? Also, since the date variable does not have component parts, will date datatype work here? Lastly, if I use timestamp data type for the start_time attribute, what should be the value I enter in the insert column- should it be 08:00:00?
I'm using SQL Server 2014.
Thank You for your help.
AFAIK it is better to use one column by type of DateTime instead of two columns which hold Date and Time separately.
Also you could simply query this column either by Date or Time by casting it to corresponding type :
DECLARE #ChangeDateTime AS DATETIME = '2012-12-09 16:07:43.937'
SELECT CAST(#ChangeDateTime AS DATE) AS [ChangeDate],
CAST(#ChangeDateTime AS TIME) AS [ChangeTime]
results to :
ChangeDate ChangeTime
---------- ----------------
2012-12-09 16:07:43.9370000