Reputation: 341
I'm trying to list all the users who are above the age of 13 and have downloaded an app in the category "Social"
. With the users date of births in ascending order.
Below I attempted to convert users date of births into an int number and use that to only display users over "13" but to no avail.
My code :
SELECT DISTINCT
CAST(u."Username" AS varchar2(20)) AS "Username",
CAST(u."FirstName" AS varchar2(15)) AS "FirstName",
CAST(u."LastName" AS varchar2(15)) AS "LastName",
TRUNC((sysdate - u."DateOfBirth")/365.25) AS "DateOfBirth"
FROM BR_USER u, BR_APPCATEGORY ap
WHERE ap."CategoryName" = 'Social' AND "DateOfBirth" > '13'
ORDER BY "DateOfBirth" ASC;
The error I receive :
ERROR at line 7:
ORA-01840: input value not long enough for date format
CREATE TABLE "BR_USER"(
"UserId" NUMBER(6,0),
"Username" VARCHAR2(35) CONSTRAINT "BR_USER_USERNAME_NN" NOT NULL ENABLE,
"FirstName" VARCHAR2(30),
"LastName" VARCHAR2(50) CONSTRAINT "BR_USER_LAST_NAME_NN" NOT NULL ENABLE,
"Email" VARCHAR2(100) CONSTRAINT "BR_USER_EMAIL_NN" NOT NULL ENABLE,
"Gender" VARCHAR2(3),
"JoinDate" DATE CONSTRAINT "BR_USER_JOINDATE_NN" NOT NULL ENABLE,
"DateOfBirth" DATE CONSTRAINT "BR_USER_DOB_NN" NOT NULL ENABLE,
"CountryId" NUMBER(3,0),
CONSTRAINT "BR_USER_EMAIL_CORRECT" CHECK ("Email" like '%@%'),
CONSTRAINT "BR_USER_EMAIL_UNIQUE" UNIQUE("Email"),
CONSTRAINT "BR_USER_ID_PK" PRIMARY KEY ("UserId") ENABLE
)
/
CREATE TABLE "BR_APPCATEGORY"(
"AppCategoryId" NUMBER(2,0),
"CategoryName" VARCHAR2(20) CONSTRAINT "BR_APPCATEGORY_NAME_NN" NOT NULL ENABLE,
"Description" VARCHAR2(100),
CONSTRAINT "BR_APPCATEGORY_PK" PRIMARY KEY ("AppCategoryId") ENABLE
)
/
Upvotes: 0
Views: 974
Reputation: 1269803
You should use direct date comparisons:
WHERE "DateOfBirth" < sysdate - interval '13' year
To be honest, this could cause a problem in leap years on Feb 29th. For some reason, Oracle allows this rare bug. So, add_months()
is recommended:
WHERE "DateOfBirth" < add_months(sysdate, -13 * 12)
Note that both of these expressions are index-friendly, meaning that they can take advantage of an index on "DateOfBirth"
, if one is available and the optimizer thinks that is a good idea.
A function such as months_between()
generally prevents an index from being used, which is why these solutions are preferable.
Upvotes: 2
Reputation: 20914
Using the linked answer in Robert Harvey's first comment to your question, plus the CREATE TABLE
statement you provided, plus your clarification that at this stage you only want users over 13 years of age, the following SQL should provide you the results you desire.
SELECT substr(u."Username", 1, 20) AS "Username"
,substr(u."FirstName", 1, 15) AS "FirstName"
,substr(u."LastName", 1, 15) AS "LastName"
,TRUNC(u."DateOfBirth") AS "DateOfBirth"
FROM BR_USER u
WHERE months_between(TRUNC(sysdate), u."DateOfBirth") / 12 > 13
ORDER BY u."DateOfBirth"
Upvotes: 0