0

好的,这是我的 SQL DB 中有两个表的问题。表 1 是一个简单的联系人表,其中包含我数据库中每个人的记录。表 2 是一个教育/考试表,其中数据库中的每个人都有一条记录,但每条记录中都有多个测试。我正在尝试查询这两个表以获取具有过期值(早于今天)的所有记录的列表,以便我可以将记录标记为删除。数据库中存储的所有日期都是过期日期。更重要的是,由于个人考试记录都存在于记录的单行中,因此即使有一个考试日期未过期,则需要保留整个记录。如果我有空值和过期日期的组合,我只能删除一条记录。不是每个人都有 4 条记录,大多数有 1 或 2 条,其余记录为 Null。

select n.id, n.FULL_NAME, e.ExamDate1, e.ExamDate2, e.ExamDate3, e.ExamDate4
from Name n inner join Education e on n.id = e.id

这给我带来了 57k 条记录,它们都是混合的。结果片段如下所示:

| 身份证 | 全名 | 考试日期1 | 考试日期 | 考试日期3 | 考试日期4 |
| 10001 | 约翰·多伊 | 2008 年 1 月 1 日 | 空 | 空 | 2015 年 10 月 25 日 |
| 10002 | 简·多伊 | 2020 年 10 月 8 日 | 2015 年 1 月 25 日 | 2014 年 4 月 16 日 | 空 |
| 10003 | 约翰·史密斯 | 2010 年 1 月 1 日 | 2008 年 6 月 5 日 | 2013 年 9 月 15 日 | 2001 年 7 月 8 日 |
| 10004 | 黛比苏 | 2020 年 8 月 14 日 | 2016 年 6 月 5 日 | 空 | 空 |
| 10005 | 苏茜 Q | 2016 年 5 月 9 日 | 2014 年 4 月 15 日 | 2017 年 4 月 9 日 | 空 |

我需要能够获取这些数据并对其进行分类并标记每个人的好坏。如果至少有一个列出的日期未过期,则为好;如果所有列出的日期已过期或所有日期均已过期并且没有日期的记录为空,则为不好。

关于最简单的方法的任何想法是什么?我正在考虑一个程序中的案例陈述,在该程序中,我使用每个考试日期的案例来遍历每条记录。有一个以空白开头的存储变量,并为该存储变量添加一个值,变量 = 变量 + 'X',在循环结束时,查看变量的值。如果该值为 yyyy,则记录被标记(显示),如果不是,则该记录被单独保留。循环完成后,将变量重置为空白并重新开始。

我希望这是有道理的,就像它在我的脑海中一样,但并不总是在纸上。

谢谢。

4

2 回答 2

0

Sql 是一种基于集合的语言。语言本身不是标记好坏,而是返回一个特定的集合。在这种情况下,您可能需要一组过期记录。您拥有面前的所有信息,因此不需要案例陈述或循环浏览数据。一般来说,你应该尽量不要循环遍历sql中的数据。

因此,您需要的是符合以下条件的所有人员的列表:考试日期 1 为空或已过期,考试 2 为空或已过期,考试 3 为空或已过期,考试 4 为空或已过期。这些条件非常好地转化为 sql。

select n.id, n.FULL_NAME, e.ExamDate1, e.ExamDate2, e.ExamDate3, e.ExamDate4
from Name n inner join Education e on n.id = e.id
where (e.ExamDate1 is null or e.ExamDate1 < cast(getDate() as date))
and (e.ExamDate2 is null or e.ExamDate2 < cast(getDate() as date))
and (e.ExamDate3 is null or e.ExamDate3 < cast(getDate() as date))
and (e.ExamDate4 is null or e.ExamDate4 < cast(getDate() as date))
于 2014-09-30T15:24:14.313 回答
0

“好”人名单

select n.id, n.FULL_NAME, e.ExamDate1, e.ExamDate2, e.ExamDate3, e.ExamDate4
from Name n inner join Education e on n.id = e.id
where
  (
    ISNULL(e.ExamDate1,'19000101') >= GETDATE()
    or
    ISNULL(e.ExamDate2,'19000101') >= GETDATE()
    or
    ISNULL(e.ExamDate3,'19000101') >= GETDATE()
    or
    ISNULL(e.ExamDate4,'19000101') >= GETDATE()
    or
  )

标记坏人(仅在名称表中)

update n
set n.YOUR_FLAG_COLUMN = 'Y'
from Name n inner join Education e on n.id = e.id
where
  (
    ISNULL(e.ExamDate1,'19000101') < GETDATE()
    and
    ISNULL(e.ExamDate2,'19000101') < GETDATE()
    and
    ISNULL(e.ExamDate3,'19000101') < GETDATE()
    and
    ISNULL(e.ExamDate4,'19000101') < GETDATE()        
  )

或者,如果您在名称和教育之间使用 ON CASCADE DELETE 甚至删除它们...

于 2014-09-30T15:28:23.237 回答