Php SQL查询,以包括在某个范围内的过期日期,但如果它们具有相同类型的另一个实例,则排除该过期日期

Php SQL查询,以包括在某个范围内的过期日期,但如果它们具有相同类型的另一个实例,则排除该过期日期,php,sql,Php,Sql,这里是详细模式下的问题。我在证书表上有证书的实例,它们都有一个类型和一个与之关联的学生。这是我想要发生的事情,我想获取所有证书,其到期日期在现在到1年的范围内。如果他们符合该参数,很好,但是如果他们的证书过期时间大于范围,并且证书类型与该范围内的证书类型相同,那么我想排除该学生-他们不需要在报告中。这是我的第一个问题: SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type

这里是详细模式下的问题。我在证书表上有证书的实例,它们都有一个类型和一个与之关联的学生。这是我想要发生的事情,我想获取所有证书,其到期日期在现在到1年的范围内。如果他们符合该参数,很好,但是如果他们的证书过期时间大于范围,并且证书类型与该范围内的证书类型相同,那么我想排除该学生-他们不需要在报告中。这是我的第一个问题:

SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type
          FROM students s, certifications c
          WHERE ( s.student_id = c.student_id )
            AND s.status='A' 
            AND s.student_type != 'B' 
            AND s.student_type != 'D'  
            AND s.student_type != 'E'
            AND s.student_type != 'W'  
            AND s.student_type != 'T'  
            AND s.student_type != 'I'  
            AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR)
          GROUP BY s.student_id
             ORDER BY s.lname, s.fname
总而言之,我遇到的问题是,如果学生的证书到期时间在一年内,并且他们有另一个相同类型的证书到期时间超过该范围,他们就会出现。那不好


是否有办法检查以确保某个证书类型在日期范围内,如果是,则确保他们没有超过该范围的同一类型证书?它不在乎是否需要另一个sql查询。

我可能过度简化了问题,但您能否不只是获得任何学生/类型组合的最大过期日期?e、 g

SELECT  s.student_id, 
        s.fname, 
        s.address1, 
        s.lname, 
        s.zip, 
        s.state, 
        s.city, 
        s.student_type
FROM    Students s
        INNER JOIN 
        (   SELECT  c.student_ID, 
                    c.Cert_Type, 
                    MAX(Expiration) AS Expiration
            FROM    Certifications c
            GROUP BY c.student_ID, c.Cert_Type
        ) c
            ON s.Student_ID = c.Student_ID
WHERE   s.Student_Type NOT IN ('B', 'D', 'E', 'W', 'T', 'I')
AND     c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR)
GROUP BY s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type
使用子查询:

SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type
  FROM students s, certifications c
  WHERE ( s.student_id = c.student_id )
    AND s.status='A' 
    AND s.student_type != 'B' 
    AND s.student_type != 'D'  
    AND s.student_type != 'E'
    AND s.student_type != 'W'  
    AND s.student_type != 'T'  
    AND s.student_type != 'I'  
    AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR)
    AND NOT EXISTS (
      SELECT c_inner.id 
      FROM certifications c_inner 
      WHERE c.expiration > DATE_ADD(NOW(), INTERVAL 1 YEAR)
        AND c.student_id = c_inner.student_id
    )
  GROUP BY s.student_id
    ORDER BY s.lname, s.fname

我认为应该可以将其重构为一个连接,这样可以提供更好的性能。

我添加了一个连接,以便在一个查询中从证书类型中提取信息。这是一个适合我的连接!非常感谢GarethD!对不起,我原来的帖子没有什么意义,那是在我工作日结束时。无论如何,谢谢你的回答,我从你的帖子中学到了很多。我还意识到我将不得不阅读更多关于“加入”的内容
SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type
  FROM students s
  JOIN certifications c ON c.student_id = s.student_id
  LEFT JOIN certifications c2 ON c2.student_id = s.student_id
AND c2.expiration > DATE_ADD(NOW(), INTERVAL 1 YEAR)
  JOIN cert_type ct ON ct.cert_type=c.cert_type
  WHERE ( s.student_id = c.student_id )
    AND s.status='A' 
    AND s.student_type != 'B' 
    AND s.student_type != 'D'  
    AND s.student_type != 'E'
    AND s.student_type != 'W'  
    AND s.student_type != 'T'  
    AND s.student_type != 'I'  
    AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR)
    AND c2.student_id is null
    ORDER BY s.lname, s.fname
SELECT s.student_id, s.fname, s.address1, s.lname, s.zip, s.state, s.city, s.student_type
  FROM students s
  JOIN certifications c ON c.student_id = s.student_id
  LEFT JOIN certifications c2 ON c2.student_id = s.student_id
AND c2.expiration > DATE_ADD(NOW(), INTERVAL 1 YEAR)
  JOIN cert_type ct ON ct.cert_type=c.cert_type
  WHERE ( s.student_id = c.student_id )
    AND s.status='A' 
    AND s.student_type != 'B' 
    AND s.student_type != 'D'  
    AND s.student_type != 'E'
    AND s.student_type != 'W'  
    AND s.student_type != 'T'  
    AND s.student_type != 'I'  
    AND c.expiration >= CURDATE() AND c.expiration <= DATE_ADD(NOW(), INTERVAL 1 YEAR)
    AND c2.student_id is null
    ORDER BY s.lname, s.fname