2017-08-30 31 views
1

基本上,我想从EXT表中的多行中检索数据。如何优化查询检查表中多行的数据?

Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDATRM') 
INTERSECT 
Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDA4RM') 
INTERSECT 
Select package_id from EXT WHERE Priority > 299 
INTERSECT 
Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Rate table rate' and ITEM_PARAM_ATTR_VALUE='0.00000953') 
INTERSECT 
Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Usage category group' and ITEM_PARAM_ATTR_VALUE='H'); 
+0

欢迎EAV世界。 – lad2025

+0

你正在使用哪些DBMS? –

+0

@YellowBedwetter其甲骨文 –

回答

0

除非我错了,它看起来喜欢,因为所有的选择所对同一个表,这个:

Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDATRM') 
INTERSECT 
Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDA4RM') 
INTERSECT 
Select package_id from EXT WHERE Priority > 299 

产生同样的结果,因为这:

Select package_id from EXT WHERE 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDATRM') 
AND 
(ITEM_PARAM_ATTR_NAME='Charge code' and ITEM_PARAM_ATTR_VALUE='WDA4RM') 
AND 
(Priority > 299) 

第二方法更具可读性,我怀疑它的执行速度也会更快。

+0

你提供的解决方案的问题是,如果你看到我的SQL它是相交的common package_ids。但是你提供的查询不会相交,它将像联盟一样工作而不会相交。例如:假设表中有3行,并且Package_id为1,其中ITEM_PARAM_ATTR_VALUE ='WDATRM'且Package_id也为ITEM_PARAM_ATTR_VALUE ='WDA4RM',另一行为Package_id为2,其中ITEM_PARAM_ATTR_VALUE ='WDATRM'您的查询将返回这两个package_ids,但它应该只返回Package_id 1 –

+0

@PalashManawat我可能在午餐前很快打字,我相信如果我使用“AND”而不是“OR”,解决方案将是功能。这样,只有所有谓词都是真的行才会返回。 – Dessma

+0

没有冒犯,但如果解决这个问题本来就是这么简单,我会知道...与AND的问题是,它不会在多行的工作....我有2问题1使用交叉口和第二个使用IN .... IN是非常非常慢,交叉口比IN快,但我觉得交叉口不是最佳.. –

0

我不知道是否会更快,但你可以给一个JOIN基础的方法了一枪

SELECT CON1.package_id 
    FROM (SELECT DISTINCT package_id 
      FROM EXT 
     WHERE ITEM_PARAM_ATTR_NAME = 'Charge code' 
      AND ITEM_PARAM_ATTR_VALUE = 'WDATRM' 
     ) CON1 
INNER 
    JOIN (SELECT DISTINCT package_id 
      FROM EXT 
     WHERE ITEM_PARAM_ATTR_NAME = 'Charge code' 
      AND ITEM_PARAM_ATTR_VALUE = 'WDA4RM' 
     ) CON2 
    ON CON1.package_id = CON2.package_id 
INNER 
    JOIN (SELECT DISTINCT package_id 
      FROM EXT 
     WHERE Priority > 299 
     ) CON3 
    ON CON1.package_id = CON3.package_id  
INNER 
    JOIN (SELECT DISTINCT package_id 
      FROM EXT 
     WHERE ITEM_PARAM_ATTR_NAME = 'Rate table rate' 
      AND ITEM_PARAM_ATTR_VALUE = '0.00000953' 
     ) CON4 
    ON CON1.package_id = CON4.package_id  
INNER 
    JOIN (SELECT DISTINCT package_id 
      FROM EXT 
     WHERE ITEM_PARAM_ATTR_NAME = 'Usage category group' 
      AND ITEM_PARAM_ATTR_VALUE = 'H' 
     ) CON5 
    ON CON1.package_id = CON5.package_id  

编辑:那第一个没有工作。 INTERSECTS可能会像它一样好。如果这个更好,我会感到惊讶,但也许。

SELECT DISTINCT package_id 
    FROM (SELECT MAX(CASE WHEN ITEM_PARAM_ATTR_NAME = 'Charge code' 
         AND ITEM_PARAM_ATTR_VALUE = 'WDATRM' THEN 1 
         ELSE 0 
       ) OVER 
       (PARTITION BY package_id) CON1, 
       MAX(CASE WHEN ITEM_PARAM_ATTR_NAME = 'Charge code' 
         AND ITEM_PARAM_ATTR_VALUE = 'WDA4RM' THEN 1 
         ELSE 0 
       ) OVER 
       (PARTITION BY package_id) CON2, 
       MAX(CASE WHEN Priority > 299 THEN 1 
         ELSE 0 
       ) OVER 
       (PARTITION BY package_id) CON3, 
       MAX(CASE WHEN ITEM_PARAM_ATTR_NAME = 'Rate table rate' 
         AND ITEM_PARAM_ATTR_VALUE = '0.00000953' THEN 1 
         ELSE 0 
       ) OVER 
       (PARTITION BY package_id) CON4, 
       MAX(CASE WHEN ITEM_PARAM_ATTR_NAME = 'Usage category group' 
         AND ITEM_PARAM_ATTR_VALUE = 'H' THEN 1 
         ELSE 0 
       ) OVER 
       (PARTITION BY package_id) CON5, 
       CON1 + CON2 + CON3 + CON4 + CON5 AS ALLCON 
      FROM EXT  
     ) TMP 
WHERE ALLCON = 5; 
+0

它做了工作,并感谢您的所有努力......我会检查它的表现是否足够好。 –

+0

从性能的角度来看,我的查询工作更快,我很抱歉地说::) –

+0

无赖,我添加了一个替代品,但我不认为它会更好。您是否在ITEM_PARAM_ATTR_NAME或ITEM_PARAM_ATTR_VALUE上定义了索引? –

0
SELECT DISTINCT (package_id) 
    FROM EXT 
WHERE Item_param_attr_name = 'Usage category group' 
    AND Item_param_attr_value = 'H' 
    AND package_id IN 
     (SELECT DISTINCT (package_id) 
      FROM EXT 
     WHERE Item_param_attr_name = 'Charge code' 
      AND Item_param_attr_value = 'WDATRM' 
      AND Priority > 299 
      AND package_id IN 
       (SELECT DISTINCT (package_id) 
        FROM EXT 
       WHERE Item_param_attr_name = 'Charge code' 
        AND Item_param_attr_value = 'WDA4RM' 
        AND package_id IN 
         (SELECT DISTINCT (package_id) 
          FROM EXT 
         WHERE ITEM_PARAM_ATTR_NAME = 'Rate table rate' 
          AND ITEM_PARAM_ATTR_VALUE = '0.00000953'))); 
+0

@YellowBedwetter这是迄今为止的最佳选择。 –

+0

@Dessma谢谢。 –