列出特定年龄段的用户

时间:2019-12-21 20:16:54

标签: sql oracle

我正在尝试列出所有13岁以上并下载了"Social"类别的应用程序的用户。用户的出生日期按升序排列。

下面,我尝试将用户的出生日期转换为整数,并使用该数字仅显示“ 13”以上的用户,但无济于事。


我的代码:

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;

我收到的错误:

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
)
/

2 个答案:

答案 0 :(得分:2)

您应该使用直接日期比较:

WHERE "DateOfBirth" < sysdate - interval '13' year

说实话,这可能会在2月29日的leap年引起问题。由于某种原因,Oracle允许此罕见的错误。因此,建议使用add_months()

WHERE "DateOfBirth" < add_months(sysdate, -13 * 12)

请注意,这两个表达式都是索引友好的,这意味着如果可以使用"DateOfBirth"上的索引并且优化器认为这是一个好主意,那么它们可以利用。

诸如months_between()之类的函数通常会阻止使用索引,这就是为什么使用这些解决方案的原因。

答案 1 :(得分:0)

使用罗伯特·哈维(Robert Harvey)对您问题的第一条评论中的链接答案,以及您提供的CREATE TABLE语句,以及您在此阶段只希望年龄超过13岁的用户的说明,以下SQL应该为您提供您想要的结果。

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"