2017-08-30 32 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謝謝。 –