Out putting birth years with TO_CHAR(M.DOB, 'YYYY') - sql

I have a database with a store of members and dates of birth.
I am to "List name and year of birth of all members in alphabetical order by family name and given name with "DHDSJHDSDH" as parent
I currently have Current Code
Everything works apart from the birthdays as for someone with a birthday in 1993 it outputs 2093.

It would certainly help if you had code or table structure posted but I will take a stab. I would imagine you want something along the lines of:
SELECT FamilyName,
GivenName,
CONVERT(varchar, yearOfBirth, 101)
FROM schema.TableYouUse
ORDER BY FamilyName;
Like I said, this may not be what you are asking at all. What I did was query up the first name, last name, and birth date of the person in the table. I used CONVERT to make the birth date column varchar instead of DATETIME that way we can format it the way we like.
Notice that CONVERT takes parameters, the first param is target expression type, the second is the target date, and lastly we use 101 to format it the way you need. Here is a link to the convert docs for more styles you can use https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15
Lastly, to address the crazy 2093 instead of 1993 that sounds like bad data entry to me.

Related

CAST and CONVERT both failing when attempting to convert string to date

I'm dealing with a table containing records from questionnaires administered to people after completing an activity. There are several questions on the questionnaire, so each person has multiple records with the same collection date, like so.
PersonID Question Result CollectedDate
-------------------------------------------------------------
1001 First activity? Yes 10/23/2022
1001 Activity date 10/20/2022 10/23/2022
1001 Activity type Painting 10/23/2022
1002 First activity? No 10/24/2022
1002 Activity date 10/23/2022 10/24/2022
1002 Activity type Writing 10/24/2022
Since my end goal is to compare the activity date with the questionnaire collection date and see how much time elapsed between them, I've altered my query a bit so I'm focusing only on each person's question regarding the activity date. It's a super simple query:
SELECT
PersonID,
Question,
Result,
CollectedDate
FROM Questionnaire
WHERE Question LIKE '%date%'
PersonID Question Result CollectedDate
-------------------------------------------------------------
1001 Activity date 10/20/2022 10/23/2022
1002 Activity date 10/23/2022 10/24/2022
My main issue is that the Result field is varchar(50) in order to accommodate text answers, so any dates seen there are actually from free text fields in the front-end interface. I've tried using both CAST() and CONVERT() to turn it into an actual date format so the difference between the dates can be calculated. I've seen both of the following errors depending on which function I'm using or which date/time style I'm attempting to apply:
Conversion failed when converting date and/or time from character string
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
I've tried:
SELECT
PersonID,
Question,
CAST(Result as date),
CollectedDate
FROM Questionnaire
WHERE Question LIKE '%date%'
and...
SELECT
PersonID,
Question,
CONVERT(DATETIME,Result,101) as Result,
CollectedDate
FROM Questionnaire
WHERE Question LIKE '%date%'
...and have tried several different styles. Does anyone have any further suggestions? Is the date itself likely the problem, or is if the fact that the Result field contains a bunch of other stuff too, even though it's currently omitted from the query results?
UPDATE: There are some kind of wonky date formats in this Result field even when I have the other question types filtered out (I hate free text). For example, there are some formatted like 05/01/2022 and others like 5/1/2022. Some others have something like 5/19/2022 - 5/20/2022, like maybe the person couldn't remember the exact date of their activity. What's the best way to deal with all of this?
You should be able to get past the error by making sure you reject any value that can't be converted to a date. Largely, that is this:
Result = CASE
WHEN ISDATE(Result) = 1 THEN CONVERT(date, Result, 101) END
You'd think it would be enough to say WHERE Question = 'Activity Date' AND ISDATE(Result) = 1, but:
Someone still might have entered bad data on that row.
SQL Server might try to perform the CONVERT() operation before the filter.
You can identify the ones that have bad data using:
WHERE Question = 'Activity Date' AND ISDATE(Result) = 0
But until you've fixed the structure and stored dates in an independent column, fixing that data just means it's a matter of time before it happens again.
You might consider, in the meantime, just displaying what the user entered as a string, instead of trying to force it to be converted to a date. Especially since 101 might be a bad guess - what if the user is from the UK or Canada? They may have entered 05/12 and meant December 5th, not May 12th.

Select all records from specified day

I have table named table_food in db with columns: first name, last name, date, food name. I want a query that returns all food names from specified date.
For example my table records looks like:
John Watson 2016-08-22 steak
John Watson 2016-08-22 burger
John Watson 2016-08-23 fries
John Watson 2016-08-23 apple
and I want to get all food names from 2016-08-23. How should I create my query?
I´m just assuming you´re using a MySQL-Database. The answer may vary for other databases.
There are two versions, depending on what you´re trying to get.
If you just want a list of all foods, including duplicates, you could use:
select food_name from table_food where date = '2016-08-23'
If you just need to get distinct values (each food name once) you could use:
select distinct(food_name) from table_food where date = '2016-08-23'
The first question could be: Which meals have been served and how many of them?
The second question could be: Which meals have been served at all (no matter how often)
It depends from the database you use.
I added also a distinct because I imagine that you need only distinct values of food names.
For MySql
select distinct(food_name) from table_food
where date = '2016-08-23'
For Oracle
select distinct(food_name) from table_food
where date = to_date('2016-08-23', 'YYYY-MM-DD')
Check for dialects of other databases.
Note that if the data stored in the date column has also hours, minutes and seconds you need a different query to extract data, for example in oracle:
select distinct(food_name) from table_food
where trunc(date) = to_date('2016-08-23', 'YYYY-MM-DD')
$date = "2016-08-23";
SELECT * FROM `table_food` WHERE `date` = '{$date}';
The reason I'd variable the date is solely down to as and when you wish to change the date. Don't get me wrong either of the above you can do. My personal preference would be to adjust the variable rather than the query.
When you need to retrieve data from a table, you'll have to specify what field you need to select from what table, under one or several conditions.
Since your condition is the date,
we'll use this syntax:
We added the word distinct in case you didn't need redundancy.
Select distinct FoodName
from Table_Food
Where date = '2016-08-23'

Average age using months_between()

So I have a table with the birth dates and I need to average the people's age. How do I do that? I know I have to use months_between(). Thank you in advance!
Why do you think you need months_between? You don't (unless you have a very specific and unusual definition of "average age").
Over a long enough period (like 40+ years, say), a person's age in years can be calculated (within a narrow approximation window) as the age in days, divided by 365.25. The age in days is simply a difference between two dates, SYSDATE and DATE_OF_BIRTH or BORN. The first one is provided by the system and the second is in your table. Assuming, that is, that you want age as of today; otherwise change SYSDATE to whatever "as-of" (fixed) date you want to use.
So, something like
select [some columns here], AVG(SYSDATE - BORN)/365.25 as avg_age
from your_table
Not clear why you would select max(born) from dual; surely you didn't call your table dual? Nor did you change the standard dual table to add your own data to it?
When people ask you what datatype you use for born in your tables, what you see on the screen when you query for it is not sufficient; the screen will show a string (it's the only thing a screen shows) and doesn't necessarily reflect what's in the database. To get the proper answer, run DESCRIBE table_name; that will show all the columns in table_name and their datatype. Note that DESCRIBE table_name is a SQL*Plus command (understood by Toad and SQL Developer - whatever you use to communicate with the database), so it doesn't need a ; or a / at the end. Just type it at the prompt and hit ENTER.
Good luck!

applying knowledge of SQL for everyday workplace activities

My question is how to properly write a SQL query for the below highlighted/bold question.
There is a table in HMO database which stores doctor's working
hours.Table has following fields
"FirstName","LastName","Date","HoursWorked". write a sql statement
which retrieves average working hours for period January-March for a
doctor with name Joe Doe.
so far i have
SELECT HoursWorked
FROM Table
WHERE DATE = (January - March) AND
SELECT AVG(HoursWorked) FROM Table WHERE FirstName="Joe",LastName="Doe"*
A few pointers as this sounds like a homework question (which we don't answer for you here, but we can try to give you some guidance).
You want to put all the things you want to return from your select first and you want to have all your search conditions at the end.
So the general format would be :
SELECT Column1,
Column2,
Column3,
FROM YourTable
WHERE Column4 = Restriction1
AND Column5 = Restriction2
The next thing you need to think about is how the dates are formatted in your database table. Hopefully they're kept in a column of type datetime or date (options will depend on the database engine you're using, eg, Microsoft SQL Server, Oracle or MySql). In reality some older databases people use can store dates in all sorts of formats which makes this much harder, but since I'm assuming it's a homework type question, lets assume it's a datetime format.
You specify restrictions by comparing columns to a value, so if you wanted all rows where the date was after midnight on the 2nd of March 2012, you would have the WHERE clause :
WHERE MyDateColumn >= '2012-03-02 00:00:00'
Note that to avoid confusion, we usually try to format dates as "Year-Month-Day Hour:Minute:Second". This is because in different countries, dates are often written in different formats and this is considered a Universal format which is understood (by computers at least) everywhere.
So you would want to combine a couple of these comparisons in your WHERE, one for dates AFTER a certain date in time AND one for dates before another point in time.
If you give this a go and see where you get to, update your question with your progress and someone will be able to help get it finished if you have problems.
If you don't have access to an actual database and need to experiment with syntax, try this site : http://sqlfiddle.com/
you already have the answer written
SELECT AVG(HoursWorked) FROM Table WHERE FirstName="Joe",LastName="Doe"*
you only need to fix the query
SELECT AVG(HoursWorked) as AVGWORKED FROM Table WHERE FirstName='Joe' AND LastName='Doe'
That query will give you the average hours worked for Joe Doe, however you only need to get between some time you add the next "AND", if you are using SQL server you can use the built in function DateFromParts(year,month,day) to create a new Date, or if you are using another Database Engine you can convert a string to a DateColumn Convert(Date,'MM/dd/yyyy')
Example
SELECT AVG(HoursWorked) as AVGWORKED FROM Table WHERE FirstName='Joe' AND LastName='Doe' AND DateColumn between DateFromParts(year,month,day) and Convert(Date,'MM/dd/yyyy')
In the example i showed both approaches (datefromparts for the initial date, and convert(date) for the ending date).

How to extract dates with datatye DATETIME from colum A in table X and put them into Table Y while changing datatype into DATE

Long title, easy meaning:
How is it possible to extract from a date like "2014-04-04 10:47:30.000", which is stored in one column, it's components like year, month and day?
I'm not interested in the time.
For example, I have a table called "Incidents". Inside the table we got a column called "IncidentID" and a column called "ReportingDate", in which dates like the above-mentionend are stored. Let's say we have about 50k Incidents, therefore we have also 50k dates.
A year has 365 days. I want to query for the count of the Incidents, which were reported on different dates - for instance on the 5th of October 2013.
So: How can I get the components of the date and put them into another table while having own columns for the components and how can I query for the Incidents as well?
I guess at first I have to change the datatype of the date from DATETIME to DATE, but I'm not quite sure how to go further. May anyone help me while giving me a code and explains me what it does for a sql-noob? :-)
To achieve this
I want to query for the count of the Incidents, which were reported on
different dates - for instance on the 5th of October 2013.
you haven't do this:
I guess at first I have to change the datatype of the date from
DATETIME to DATE, but I'm not quite sure how to go further.
Just query
SELECT
IncidentID
FROM incidents
WHERE ReportingDate >= '20131005'
AND ReportingDate < '20131006'