使用WHERE和CASE进行MySQL查询

时间:2016-01-12 14:47:59

标签: mysql

我真的不知道这是否可行,但我会暴露我的问题。

我有两张表casesprogress

+----------+--------------+---------------------+---------+------+
| id_cases |     name     |    date_surgery     | archive | done |
+----------+--------------+---------------------+---------+------+
|        1 | Cranioplasty | 2016-02-01 00:00:00 |       1 |    0 |
|        2 | Cranioplasty | 2016-02-02 00:00:00 |       0 |    0 |
|        3 | Other        | 2016-02-03 00:00:00 |       0 |    0 |
|        4 | Osteotomy    | 2016-02-04 00:00:00 |       0 |    0 |
|        5 | Bone Tumor   | 2016-02-05 00:00:00 |       1 |    1 |
+----------+--------------+---------------------+---------+------+

进度(包含数千条记录)

+-------------+---------+---------+---------+
| id_progress | task_id | case_id | current |
+-------------+---------+---------+---------+
|           1 |  103006 |       1 |       0 |
|           2 |  103002 |       1 |       1 |
|           3 |  103003 |       1 |       1 |
|           4 |  201006 |       5 |       0 |
|           5 |  201007 |       5 |       1 |
|        .... |     ... |     ... |      ...|
+-------------+---------+---------+---------+

表格之间的链接是cases.id_cases = progress.case_id

我想选择所有存档并且已完成= 0的情况。我还想获得与此案例相关的一些进展

我想了一个条件来选择与cases.name的结果相关的特定范围的task_id。

基本上我想要这个

SELECT id_cases, name, date_surgery, task_id, current
FROM cases 
LEFT JOIN progress on progress.case_id = cases.id_cases 
WHERE archive = 0 AND done = 0 

但如果名字是Cranioplasty我只想要progress.task_id等于103006,103002和105002.对于骨肿瘤我想要201006,205003和207001.这个用于每个不同的名字。

id_cases和task_id之间没有逻辑。我必须对此进行硬编码。

我尝试了不同的东西,但没有一个成功

SELECT id_Cases, name, date_surgery, task_id, current
from cases 
left join progress on progress.case_id = cases.id_cases 
where archive = 0 and done = 0 
and case when name='Cranioplasty' then task_id=103006 and task_id=103002 else
case when name='Bone Tumor' then task_id=201006 else
case when name='Osteotomy' then task_id=301002 else
case when name='MBIO' then task_id=401006 end end end end 
order by name, date_surgery

很好,我试着得到这个结果(task_id并不重要,我只想得到current)的结果

+------+--------------+-----------+--------+-------+--------+-------+--------+-------+
| case |     name     | date_surg | task_1 | 1_res | task_2 | 2_res | task_3 | 3_res |
+------+--------------+-----------+--------+-------+--------+-------+--------+-------+
| 1    | Cranioplasty | date      | 103006 |     0 | 103002 |     0 | 105002 |     1 |
| 1    | Cranioplasty | date      | 103006 |     1 | 103002 |     1 | 105002 |     0 |
| 1    | Cranioplasty | date      | 103006 |     1 | 103002 |     0 | 105002 |     1 |
| 2    | Cranioplasty | date      | 103006 |     0 | 103002 |     1 | 105002 |     0 |
| 2    | Cranioplasty | date      | 103006 |     1 | 103002 |     0 | 105002 |     1 |
| 2    | Cranioplasty | date      | 103006 |     0 | 103002 |     1 | 105002 |     1 |
| 3    | Bone Tumor   | date      | 201006 |     1 | 205003 |     0 | 205005 |     0 |
| 3    | Bone Tumor   | date      | 201006 |     0 | 205003 |     1 | 205005 |     1 |
| ...  |              |           |        |       |        |       |        |       |
+------+--------------+-----------+--------+-------+--------+-------+--------+-------+

PS:我只是把我的桌子作为一个例子来帮助理解这个问题。它不包括所有记录

我知道我可以使用临时表或虚拟表,但我想知道如何只使用查询解决此问题

1 个答案:

答案 0 :(得分:1)

嗯,无论如何,这是对硬编码名称和任务ID之间关系的不良做法。您需要将它们存储在数据库或smthng中。因此,您可以加入该表并在1个查询中执行此操作。

如果您不想或者不想将它们保存到数组中,那么您可以动态生成具有此条件的查询部分(如果可能)。


    select
            a.id_cases,
            a.name,
            b.task_id,
            b.current
        from
            cases a
        left join
            progress b ON b.case_id = a.id_cases
        where
            a.archive = 0
            and a.done = 0
            and (
                (b.task_id in (103006,103002,105002) and a.name = 'Cranioplasty')
                OR (b.task_id in (201006,205003,207001) and a.name = 'Bone Tumor')
            )

如果您可以使用任何语言来生成此部分


    and (
            (b.task_id in (103006,103002,105002) and a.name = 'Cranioplasty')
                OR (b.task_id in (201006,205003,207001) and a.name = 'Bone Tumor')
        )

做到这一点。例如在php


    foreach($arRealtions as $name => $taskIDs)
    {
        $query .= '(b.task_id in ('.implode(',',$taskIDs).') and a.name = "'.$name.'")';
    }