简体   繁体   English

SQL查询-比较行值

[英]SQL Query - compare row values

Ok, so here is the problem I have two tables in my SQL DB. 好的,这就是问题所在,我的SQL DB中有两个表。 Table 1 is a simple contact table with a record for each individual in my DB. 表1是一个简单的联系表,其中包含我数据库中每个人的记录。 Table 2 is an education/Exam table where there is a single record for each individual in the DB but each record has multiple tests in it. 表2是一个教育/考试表,其中数据库中每个人都有一个记录,但是每个记录中都有多个测试。 I am trying to query the two tables to get me a list of all records who have expired values(older than today) so I can flag the record for deletion. 我正在尝试查询两个表,以获取具有过期值(比今天更旧)的所有记录的列表,以便我可以将记录标记为删除。 All dates stored in the DB are the expire dates. 数据库中存储的所有日期均为过期日期。 The kicker on this is that since an individuals exam records all exist in a single row for the record, if even one of the exam dates is not expired, the entire record needs to be kept. 更重要的是,由于单个考试记录的所有记录都存在于该记录的一行中,因此,即使其中一个考试日期都没有过期,也需要保留整个记录。 I can only delete a record if I have a combination of null values and expired dates. 如果我具有空值和过期日期的组合,则只能删除一条记录。 Not everyone has 4 records, most have one or two with the remaining records as Null. 并非每个人都有4条记录,大多数没有一个或两个,其余记录为Null。 So here is my code to get the data: 所以这是我的代码来获取数据:

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

This gets me 57k records and they are all a mix. 这使我获得了57,000条记录,而且它们都是混合的。 A snippet of the results look like this: 结果片段如下所示:

| | ID | ID | FullName | 全名| ExamDate1 | ExamDate1 | ExamDatew | ExamDatew | ExamDate3 | ExamDate3 | ExamDate4 | ExamDate4 |
| | 10001 | 10001 | John Doe | 约翰·杜 1/1/2008 | 1/1/2008 | Null | 空| Null | 空| 10/25/2015 | 2015年10月25日|
| | 10002 | 10002 | Jane Doe | 简·杜 10/8/2020 | 2020年10月8日| 1/25/2015 | 2015年1月25日| 4/16/2014 | 2014年4月16日| Null | 空|
| | 10003 | 10003 | John Smith | 约翰·史密斯| 1/1/2010 | 1/1/2010 | 6/5/2008 | 6/5/2008 | 9/15/2013 | 9/15/2013 | 7/8/2001 | 2001年7月8日|
| | 10004 | 10004 | Debbie Sue | 黛比·苏(Debbie Sue) 8/14/2020 | 2020年8月14日| 6/5/2016 | 2016年6月5日| Null | 空| Null | 空|
| | 10005 | 10005 | Suzy Q | Suzy Q | 5/9/2016 | 5/9/2016 | 4/15/2014 | 2014年4月15日| 4/9/2017 | 4/9/2017 | Null | 空|

I need to be able to take this data and sort through it and flag each person on good or bad. 我需要能够获取这些数据并对其进行排序,并标记每个人的好坏。 Good if at least one listed date is not expired and bad if all listed dates are expired or all dates are expired and the records without dates are null. 如果至少一个列出的日期未到期,则为好;如果所有列出的日期均已到期或所有日期都已到期,且没有日期的记录为空,则不好。

Any ideas on what the easiest way to do this is? 关于最简单的方法有什么想法吗? I was thinking a case statement in a procedure where I run through each record using a case for each exam date. 我在考虑一个过程中的案例陈述,在该过程中,我使用每个考试日期的案例来遍历每个记录。 Have a stored variable that starts as blank and add a value to that stored variable as variable = Variable + 'X' and at the end of the cycle, look at the value of the variable. 拥有一个以空白开头的存储变量,并向该存储变量添加一个值,即variable = Variable +'X',并在循环结束时查看该变量的值。 If the value is yyyy then the record is flagged(shown) if not, then the record is left alone. 如果值是yyyy,那么该记录将被标记(如果未显示),则该记录将被保留。 Once the cycle is done, reset the variable to blank and start it over. 循环完成后,将变量重置为空白并重新开始。

I hope this is making sense as it does in my head but not always on paper. 我希望这是合理的,就像在我脑海中那样,但并非总是在纸上。

Thanks. 谢谢。

Sql is a set based language. Sql是一种基于集合的语言。 Rather than flagging as good or bad, the language itself is meant to return a specific set. 语言本身不是要返回好坏标志,而是要返回特定的集合。 In this case, you probably want the set of expired records. 在这种情况下,您可能需要一组过期的记录。 You have all the information in front of you, so a case statement or cycling through data is not necessary. 您已经掌握了所有信息,因此无需执行案例说明或循环浏览数据。 In general, you should try not to cycle through data in sql. 通常,您应该尝试不循环遍历sql中的数据。

So, what you want is a list of all the people that fit the following criteria: Exam Date 1 is null or expired and exam 2 is null or expired and exam 3 in null or expired and exam 4 is null or expired. 因此,您想要的是一个符合以下条件的所有人员的列表:考试日期1为空或过期,考试2为空或过期,考试3为空或过期,考试4为空或过期。 These conditions translate into sql really nicely. 这些条件可以很好地转换为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))

list of "good" guys “好人”名单

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
  )

flag bad guys (only in Name table) 标记坏人(仅在“名称”表中)

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

or if you have foregin key between Name and Education with ON CASCADE DELETE even DELETE them... 或者,如果您在名称和教育之间有预想的键,并且进行了级联删除,甚至将其删除...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM