如何查询sql交叉引用表

时间:2014-01-25 22:26:07

标签: mysql sql cross-reference

我是SQL的新手,有些问题希望你能帮助我:

MYSQL5

表格TRAINING_REQUESTS

+------------+--------+
|    ID_TR   |  FIELD |
+------------+--------+
|      ...   |   ..   |
|      254   |   ..   |
|      ...   |   ..   |
|      286   |   ..   |
|      ...   |   ..   |
|      401   |   ..   |
|      ...   |   ..   |
|      405   |   ..   |
|      406   |   ..   |
|      ...   |   ..   |
+------------+--------+

表格PLANNING_REQUESTS

+----------+----------+----------+
| ID_PR    | ID_TR    |  TRAINER |
+----------+----------+----------+
|      ... | ...      | ...      |
|      475 | 254      |  NULL    |
|      476 | 254      |  NULL    |
|      477 | 254      |  NULL    |
|      478 | 286      |  NULL    |
|      479 | 286      |  FREE    |
|      480 | 286      |  FREE    |
|      481 | 401      |  FREE    |
|      482 | 401      |  1       |
|      483 | 401      |  FREE    |
|      484 | 405      |  NULL    |
|      485 | 405      |  1       |
|      486 | 405      |  5       |
|      487 | 405      |  FREE    |
|      488 | 406      |  1       |
|      489 | 406      |  5       |
|      490 | 406      |  5       |
|      491 | 406      |  2       |
|      ... | ...      |  ...     |
+----------+----------+----------+

我需要3件事:

预期结果

约束:所有training_requests(ID_TR)都不正常,这意味着 (>>具有所有分配计划请求的所有培训请求(ID_TR)(ID_PR) 与训练师同等(空或免费)

+------------+-------+
|    ID_TR   | field |
+------------+-------+
|      254   |   ..  |
|      286   |   ..  |
+------------+-------+

约束:所有training_requests(ID_TR)几乎都可以,这意味着 (>>具有所有分配计划请求的所有培训请求(ID_TR)(ID_PR) 与培训师至少一次不同(空或免费) 而不是所有与训练师分配(不同于空或免费)

+------------+-------+
|    ID_TR   | FIELD |
+------------+-------+
|      405   |   ..  |
+------------+-------+

约束:所有的训练请求都不正常且几乎没问题

+------------+------+
|    ID_TR   |FIELD |
+------------+------+
|      405   |  ..  |
|      254   |  ..  |
|      286   |  ..  |
+------------+------+
感谢所有人!

2 个答案:

答案 0 :(得分:0)

可以通过以下方式(可能效率低下)完成:

#1 不行

SELECT tr.*
FROM TRAINING_REQUESTS tr
JOIN PLANNING_REQUESTS pr ON tr.id_tr = pr.id_tr
GROUP BY pr.id_tr
HAVING SUM(CASE WHEN pr.trainer IS NULL or pr.trainer = 'FREE' THEN 1 ELSE 0 END) = COUNT(*)
;

#2 接近确定

SELECT tr.*
FROM TRAINING_REQUESTS tr
WHERE EXISTS (SELECT 1 
              FROM PLANNING_REQUESTS pr 
              WHERE tr.id_tr = pr.id_tr 
              AND pr.trainer IS NOT NULL AND pr.trainer <> 'FREE') 
  AND EXISTS (SELECT 1 
              FROM PLANNING_REQUESTS pr 
              WHERE tr.id_tr = pr.id_tr 
              AND (pr.trainer IS NULL OR pr.trainer = 'FREE'))        
;

#3

    SELECT tr.*
    FROM TRAINING_REQUESTS tr
    WHERE EXISTS (SELECT 1 
                  FROM PLANNING_REQUESTS pr 
                  WHERE tr.id_tr = pr.id_tr 
                  AND (pr.trainer IS NULL OR pr.trainer = 'FREE'))        
;

以下是SQL Fiddle的结果。

请注意,我在#2(以及#3)中的结果与您的结果不同,因为它们包括 401

答案 1 :(得分:0)

    SELECT tr.ID_TR,tr.field 
    FROM planning_requests pr 
    INNER JOIN training_requests tr 
    ON tr.ID_TR = pr.ID_TR 
    WHERE pr.ID_TR NOT IN 
      (
      SELECT cpr.ID_TR 
      FROM planning_requests cpr 
      WHERE trainer IS NOT NULL AND trainer <> 'FREE' 
      ) 
    GROUP BY ID_TR