无意义导致SQL查询

时间:2014-03-06 17:31:19

标签: sql oracle

当我运行4个不同的查询时,我得到了一些无意义的结果。

主要是:

SELECT distinct p.id 
FROM praxis px,basis_medikation bm,therapie_zyklus_medikation tzm,therapie_zyklus tz,therapie t,patient p, behandlung b 
WHERE 1=1 
AND EXISTS (select * from diagnose d, diagnose_mamma dm, tumor_status ts where d.patient_id = p.id and d.diagnose_mamma_id = dm.id and d.deleted = 0  
   and ts.tumorstatus_m in ('M1') 
   and d.datum < t.datum 
   and (ts.id = dm.tumorstatus_id or ts.id = dm.tumorstatus_rechts_id)) 
 AND px.ID = p.praxis_ID AND px.testpraxis = 0 AND tz.deleted = 0  and tzm.deleted = 0 and t.deleted = 0 AND p.ID = t.patient_ID AND t.ID = tz.therapie_id AND tz.ID = tzm.therapiezyklus_id AND tzm.basis_medikation_id = bm.ID 
 AND t.datum >= to_date('2009-10-01', 'yyyy-MM-dd') AND t.datum < to_date('2013-10-01', 'yyyy-MM-dd') 
 AND t.behandlung_id = b.id
 AND b.deleted = 0
 AND ( 
       ( 
        bm.atcaname in ('Medizin1','Medizin2','Medizin3','Medizin4')  
        AND bm.product_name <> 'Medizin0'  
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       ) 
       OR ( 
        bm.atcaname in ('Medizin1','Medizin2','Medizin3','Medizin4')  
        AND bm.product_name <> 'Medizin0' 
        AND EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       ) 
       OR ( 
        bm.atcaname in ('Medizin1','Medizin2','Medizin3','Medizin4')  
        AND bm.product_name <> 'Medizin0'  
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       ) 
       OR ( 
        bm.atcaname not in ('Medizin1','Medizin2','Medizin3','Medizin4') 
        AND bm.product_name = 'Medizin0'  
        AND EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       )
       OR ( 
        bm.atcaname not in ('Medizin1','Medizin2','Medizin3','Medizin4') 
        AND bm.product_name = 'Medizin0'  
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       ) 
       OR ( 
        bm.atcaname not in ('Medizin1','Medizin2','Medizin3','Medizin4') 
        AND bm.product_name = 'Medizin0'  
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin5') 
        AND NOT EXISTS (select * from basis_medikation bm2, therapie_zyklus_medikation tzm2, therapie_zyklus tz2 where tz2.therapie_id = tz.therapie_id AND tz2.ID = tzm2.therapiezyklus_id AND tzm2.basis_medikation_id = bm2.ID and bm2.atcaname = 'Medizin6') 
       ) 
      ) ;

选择仅使用Medizin1或Medizin2或Medizin3或Medizin4治疗的乳腺癌患者,以及将任何这些药物与Medizin5或Medizin6联合治疗的患者,以及使用Medizin0和Medizin5治疗的患者,以及那些接受过Medizin0和Medizin6治疗的患者以及仅接受过Medizin0治疗的患者......

对于第二个查询,我只添加条件

AND b.line = 1

对于我添加的第三个查询:

AND b.line = 2

第四个:

AND b.line > 2

当第一个查询的结果数量低于其他三个查询的结果总和时,无效就会出现......应该等于或小于......我认为..

但实际上我错过了一些东西......

1 个答案:

答案 0 :(得分:1)

  

当第一次查询的结果数量时,就会出现废话   低于其他三个查询结果的总和......   应该等于或小于......我想..

我认为你的逻辑是有缺陷的,但它确实取决于你的数据。

如果你有同一个patient.id,其中behandlung.line为1,一个为2,一个为3,那么所有四个ID都会被列出一次您的查询(因为distinct)。这并不意味着它是错误的,但过滤后的查询的计数总和将为3,而未过滤的查询仍然只有一行。

count(distinct id)count (id)不同,与“

”无法比较
count(distinct case when line = 1 then id end)
  + count(distinct case when line = 2 then id end)
  + count(distinct case when line > 2 then id end)

如果没有distinct你的逻辑适用,虽然exists窗台会使它复杂化。

也许一个例子会有所帮助,简化为忽略所有连接等等:

create table t42 (id number, line number);
insert into t42 (id, line) values (1, 1);
insert into t42 (id, line) values (1, 2);
insert into t42 (id, line) values (2, 1);
insert into t42 (id, line) values (2, 2);
insert into t42 (id, line) values (2, 3);
insert into t42 (id, line) values (3, 2);

您的第一个查询找到3行:

select distinct id from t42;

        ID
----------
         1 
         2 
         3 

 3 rows selected 

您的第二个查询找到两行,但这两个ID(当然)也包含在第一个查询结果中:

select distinct id from t42 where line = 1;

        ID
----------
         1 
         2 

 2 rows selected 

第三个查询找到三行,这次完全复制第一个查询的结果集(在这个非常人为的情况下),来自第二个查询的那些:

select distinct id from t42 where line = 2;

        ID
----------
         1 
         2 
         3 

 3 rows selected 

并且您的第三个查询只找到一行,该行位于以前的所有结果集中:

select distinct id from t42 where line > 2;

        ID
----------
         2 

 1 rows selected 

所以第一个查询找到三行,少于其他三行找到的行的总和 - 2 + 3 + 1是六行。所有结果集都是正确的,但您无法比较总行数,因为多个集合中包含相同的ID。 ID 1计算两次,2计算三次,3计算一次。

结果集中的ID总数是相同的 - 毕竟它是相同的三个IDS - 并且没有ID神奇地出现在原始未过滤的查询中不存在的三个过滤查询中。但你必须消除重复,以进行任何比较。例如,联合三个过滤的查询并计算所有三个中剩余的不同ID的数量将匹配原始查询。 (在这种情况下;你说你的行有line < 1,所以在你的真实查询中总数会低于你的预期。)