6

詳細モードの問題は次のとおりです。認定テーブルに認定のインスタンスがあり、それらにはすべてタイプと学生が関連付けられています。これが私がやりたいことです。日付範囲内(今から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 は、前の sql ステートメントに基づいて証明書の情報です。

SELECT c.cert_num, c.date, expiration, ct.name, ct.cert_type, c.cert_id, c.student_id
              FROM  certifications c, cert_type ct 
              WHERE student_id = '{$Row['student_id']}'
              AND ct.cert_type = c.cert_type
              ORDER BY ct.name ASC, expiration DESC

要約すると、私が直面している問題は、証明書の有効期限が今から 1 年以内にある場合、および有効期限が範囲を超える同じタイプの別の証明書を持っている場合に学生が現れることです。それは良くないね。

特定の証明書タイプが日付の範囲内にあることを確認する方法はありますか?もしそうなら、範囲を超える同じタイプの証明書がないことを確認してください。別の SQL クエリが必要かどうかは気にしません。

4

3 に答える 3

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

これを結合にリファクタリングできるはずだと思います。これにより、パフォーマンスが向上する可能性があります。

于 2012-10-29T17:29:33.777 に答える
1

問題を単純化しすぎている可能性がありますが、学生/タイプの組み合わせの最大有効期限を取得することはできませんか? 例えば

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
于 2012-10-29T17:24:24.697 に答える
0
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
于 2012-10-29T17:49:06.050 に答える