Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm trying to generate a report that only shows clients that are age 65 years and up. I'm wondering what the SQL equivalent of months_between is and also how to correctly limit the report to clients 65+ years-old. I've included my statement below. Any assistance is appreciated. Thank you.
SELECT person.idFamily AS Family_ID, person.id AS Person_ID,(SELECT person.firstName+ ', ' + person.lastName) AS Name, person.Race AS Race, person.Ethnicity as Ethnicity, family.capidCounty AS County, Person.BirthDate AS [DateofBirth], trunc(months_between(sysdate,DateofBirth)/12))AS Age
FROM Family
LEFT JOIN person ON family.Id = person.idFamily
This should work for getting people older than 65 years and their age. DATEDIFF calculates the difference between two dates and DATEADD can add/subtract from dates.
select *, DATEDIFF(year,BirthDate,getdate()) as Age from Person where BirthDate < DATEADD(year, -65, getdate())
More about DATEDIFF and DATEADD
Well something like this should work in SQL Server:
SELECT p.idFamily AS Family_ID, p.id AS Person_ID,
(p.firstName + ', ' + p.lastName) AS Name, p.Race AS Race, p.Ethnicity as Ethnicity,
f.capidCounty AS County, p.BirthDate AS [DateofBirth],
datediff(month, dateofbirth, getdate()) / 12 as age
FROM Family f LEFT JOIN
person p
ON f.Id = p.idFamily;
This is not an exact match, but the logic is probably good enough. Note that the age will increment on the first of the month of the month with the birthday.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 22 days ago.
This post was edited and submitted for review 22 days ago.
Improve this question
I have an SQL table where I have employee logs and the states of the log state 255 being (check-in) and state 1 being checked-out
I want to have the minimum check-in time and the max checkout time of each day date as a result.
This is the table that I have.
This is the Query
select [full name],
(SELECT MIN(time) AS CHECKIN FROM attendance WHERE state = 255 and fingerprint = id) checkin,
(SELECT MAX(time) AS CHECKIN FROM attendance WHERE state = 1 and fingerprint = id) checkout,
cast (date as date)
FROM employee full outer join attendance on fingerprint = id
group by id,fingerprint,[full name],date
The problem is that it selects the minimum and Max time but not by date
it basically searches the min and max times across all dates instead of each day as its own
notice how it gave the checkin (2:00) and checkout(8:00) for Jon considering the fact that dates are in diffrent years
Is the query good, or am I doing it wrong?
Your query is almost correct, the mistake is that the group by clause in your query groups by id and then fingerprint and groups further by [full name] and then by date. Instead, you need to group only by [full name] and date:
select [full name],
MIN(
CASE
WHEN state = 255 and fingerprint = id THEN time
ELSE 999999
END
) checkin,
MAX(
CASE
WHEN state = 1 and fingerprint = id THEN time
ELSE -1
END
) checkout,
cast (date as date)
FROM employee full outer join attendance on fingerprint = id
group by [full name],date
How can I alter the SQL query to not return a 3 for customer Mike since he is not 3 years old yet. As you can see the customer turns 3 in December of 2021. But my query is giving him the age of 3. Is there anyways to alter or make a query that gives him the correct age?
SELECT
id,
name,
dob,
DATEDIFF(YYYY, dob, GETDATE())
FROM
customer
WHERE
DATEDIFF(YYYY, dob, GETDATE()) >= 2
AND DATEDIFF(YYYY, dob, GETDATE()) <= 4
Results:
id name dob datediff
-------------------------------
1 Mike 2018-12-05 3
There are many varied solutions to this issue on SQL Server. This answer is based on a Stack Overflow answer from a question where the accepted answer is not the best answer imo. When it comes to calculating "age from birth" there are advantages to using date format 112. You could try calculating the customer age something like this
declare
#as_of datetime=getdate(),
#bday datetime='2018-12-05';
select
(0 + Convert(Char(8),#as_of,112) - Convert(Char(8),#bday,112))/10000 age;
age
2
If you want an integer number of years (no fractional part)...
SELECT
*,
CASE
WHEN DATEADD(year, diff.years, customer.dob) > GETDATE()
THEN diff.years - 1
ELSE diff.years
END
AS age
FROM
customer
CROSS APPLY
(
SELECT DATEDIFF(year, customer.dob, GETDATE()) AS years
)
AS diff
WHERE
customer.dob > DATEADD(year, -5, CAST(GETDATE() AS DATE)) -- Born more recently than 5 years ago, so at most 4 years 11 month and 30 days old
AND customer.dob <= DATEADD(year, -2, CAST(GETDATE() AS DATE)) -- Born two years ago or earlier, so at least 2 years and 0 days old
The cross apply is just so that I can write the DATEDIFF() once and refer to it as many times as I like (Don't Repeat Yourself).
But then I also refactored the where clause. By moving the calculation to be on GETDATE() rather than on the dob column, I both make the maths simpler (than the case statement), but also make it so that any index on dob can be used (SARGable).
CAST(GETDATE() AS DATE) just removes the time part of today's date, on the assumption your dob (and calculations) don't account for the exact time they were born ;)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a query that I inherited:
SELECT SUM(Credit) AS Total, Account, Date
FROM
(
SELECT DISTINCT
CONVERT(char(10), dbo.vCustomer_Invoice.Accounting_Distribution__Document_Date, 101) AS Date
, dbo.vCustomer_Invoice.Accounting_Distribution__Amount_Credit AS "Credit"
, dbo.vCustomer_Invoice.Accounting_Distribution__GL_Account AS "Account"
FROM dbo.vCustomer_Invoice
WHERE CONVERT(char(10), dbo.vCustomer_Invoice.Accounting_Distribution__Document_Date, 101) = '11/03/2020' AND (dbo.vCustomer_Invoice.Accounting_Distribution__GL_Account LIKE '4000%' OR dbo.vCustomer_Invoice.Accounting_Distribution__GL_Account LIKE '4100-700-%')
)
AS D
Group By Account, Date;
This gives me a total by each GL_Account for a date. I'd like to now add a column that Sums by Date. I have in the past used a UNION ALL but I can't get that to work with this query configuration.
Any help would be appreciated.
You can use SUM() window function for this new column:
SELECT SUM(Credit) AS Total,
Account,
Date,
SUM(SUM(Credit)) OVER (PARTITION BY Date) AS Total_By_Date
FROM (
SELECT DISTINCT
CONVERT(CHAR(10), Accounting_Distribution__Document_Date,101) AS Date,
Accounting_Distribution__Amount_Credit AS Credit,
Accounting_Distribution__GL_Account AS Account
FROM dbo.vCustomer_Invoice
WHERE CONVERT(CHAR(10), Accounting_Distribution__Document_Date, 101) = '11/03/2020'
AND (Accounting_Distribution__GL_Account LIKE '4000%' OR Accounting_Distribution__GL_Account LIKE '4100-700-%')
) AS D
GROUP BY Account, Date;
I have a table, PATIENT, that has birth dates. I need to run a query that returns only those patients that are 3 years older than the youngest.
I am trying to find a good intro tutorial on nested sql statements because my online class is terrible.
This is as far as I've got:
SELECT Phone, Birthday
FROM PATIENT
WHERE Birthday >(
SELECT *
FROM PATIENT
GROUP BY Birthday
ORDER BY Birthday DESC
SELECT MIN(Birthday) AS MinAges
FROM PATIENT);
Don't google for "nested" that is a different thing. Google "subqueries".
SELECT Phone, Birthday
FROM PATIENT
WHERE Birthday - 2 > (
SELECT MIN(Birthday)
FROM PATIENT
);
Here we select those two fields from patient where the birthday is greater then a nested select where we take the least recent birthday and add 3 years to it. Hopefully this points you in the right direction.
SELECT Phone, Birthday
FROM PATIENT
WHERE Birthday >(
SELECT DateAdd(yy, 3, Cast(MIN(Birthday) As datetime))
FROM PATIENT);
If by 3 years older you mean that you want the years of the birthday have a difference of 3 then you can use the DateAdd() function:
select phone, birthday from patient
where year(DateAdd('yyyy', -3, birthday)) = (
select year(min(birthday))
from patient
)
or
select phone, birthday from patient
where year(birthday) - 3 = (
select year(min(birthday))
from patient
)
You can use a subquery to get the oldest birthdate and then date comparisons. This looks like:
select p.*
from patient as p,
(select max(birthday) as max_birthday
from patient
) as m
where p.birthday <= dateadd("yyyy", -3, m.max_birthday) and
p.birthday > dateadd("yyyy", -4, m.max_birthday);
Note that this is precisely 3 years, based on the day of the your
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a requirement, there is a table CR. Type is a field here. Now it has values like A,B,C. I need separate counts for CR records having type A in month Jan,Feb,...Dec 2013.Same for Type B and C in SQL SERVER 2008. A, B, C will be column headers and count of each for a month-year combination comes under it.
Can someone help me here?
You need google first before asking this...
SELECT * FROM
(SELECT type, datepart(mm, date) month, count(1) cn
FROM CR
WHERE datepart(yyyy, date) = '2013'
GROUP BY type, datepart(mm, date)
) AS t
PIVOT(MIN(cn) FOR type IN ([A], [B], [C])) AS m
Assuming that the CR table have a datetime field called dat you can GROUP BY MONTH in this way :
SELECT DATEPART(Month, dat) AS month, Type
FROM CR
WHERE DATEPART(Year, dat) = 2013
GROUP BY Type , DATEPART(Year, dat), DATEPART(Month, dat)