2017-10-10 5 views
0

Ce but de la requête est de compter chaque ID unique (LUID_NO) pour quatre variantes différentes du même type d'élément. Cela fonctionne comme prévu.
Maintenant à ma question, cette requête peut-elle être simplifiée ou écrite d'une autre manière?
Quand je le regarde, je ne peux pas oublier qu'il serait probablement possible de l'écrire d'une manière beaucoup plus simple.Possible de simplifier SQL?

SELECT 
    (SELECT COUNT(DISTINCT ICL.LUID_NO) 
      FROM  L2000.ITEM_CARRIER IC 
      INNER JOIN L2000.ITEM_UNITS_DEFINITION IUD ON IUD.PV_ID=IC.PV_ID AND IUD.STORER_ID=IC.STORER_ID AND IUD.ITEM_ID=IC.ITEM_ID 
      INNER JOIN L2000.ITEM_CARRIER_LUID ICL ON ICL.ITEM_CARRIER_NO=IC.ITEM_CARRIER_NO 
      INNER JOIN L2000.ITEM_PROPERTY IP ON IC.PROPERTY_INDEX=IP.PROPERTY_INDEX 
      INNER JOIN L2000.ITEM I ON I.ITEM_ID = IC.ITEM_ID AND I.STORER_ID = IC.STORER_ID 
        WHERE  IC.PV_ID = 'B2' 
        AND  IP.BLOCK_CODE IS NULL 
        AND  IUD.UOM_QTY = ICL.PHYSIC_QTY 
        AND  IUD.UNIT_DEF_ID = 'LU' 
        AND  IC.STORER_ID = 'PG' 
        AND  ICL.PHYSIC_QTY > 0 
        AND  I.ITEM_DESC LIKE '#%' 
        AND  I.ITEM_GROUP_ID IN ('BABYCARE','FEMCARE') 
    )AS B2_PALLETS, 
    (SELECT COUNT(DISTINCT ICL.LUID_NO) 
      FROM  L2000.ITEM_CARRIER IC 
      INNER JOIN L2000.ITEM_UNITS_DEFINITION IUD ON IUD.PV_ID=IC.PV_ID AND IUD.STORER_ID=IC.STORER_ID AND IUD.ITEM_ID=IC.ITEM_ID 
      INNER JOIN L2000.ITEM_CARRIER_LUID ICL ON ICL.ITEM_CARRIER_NO=IC.ITEM_CARRIER_NO 
      INNER JOIN L2000.ITEM_PROPERTY IP ON IC.PROPERTY_INDEX=IP.PROPERTY_INDEX 
      INNER JOIN L2000.ITEM I ON I.ITEM_ID = IC.ITEM_ID AND I.STORER_ID = IC.STORER_ID 
        WHERE IC.PV_ID = 'B3' 
        AND  IP.BLOCK_CODE IS NULL 
        AND  IUD.UOM_QTY = ICL.PHYSIC_QTY 
        AND  IUD.UNIT_DEF_ID = 'LU' 
        AND  IC.STORER_ID = 'PG' 
        AND  ICL.PHYSIC_QTY > 0 
        AND  I.ITEM_DESC LIKE '#%' 
        AND  I.ITEM_GROUP_ID IN ('BABYCARE','FEMCARE') 
    )AS B3_PALLETS, 
    (SELECT COUNT(DISTINCT ICL.LUID_NO) 
      FROM  L2000.ITEM_CARRIER IC 
      INNER JOIN L2000.ITEM_UNITS_DEFINITION IUD ON IUD.PV_ID=IC.PV_ID AND IUD.STORER_ID=IC.STORER_ID AND IUD.ITEM_ID=IC.ITEM_ID 
      INNER JOIN L2000.ITEM_CARRIER_LUID ICL ON ICL.ITEM_CARRIER_NO=IC.ITEM_CARRIER_NO 
      INNER JOIN L2000.ITEM_PROPERTY IP ON IC.PROPERTY_INDEX=IP.PROPERTY_INDEX 
      INNER JOIN L2000.ITEM I ON I.ITEM_ID = IC.ITEM_ID AND I.STORER_ID = IC.STORER_ID 
        WHERE IC.PV_ID = 'B2' 
        AND  IP.BLOCK_CODE IS NOT NULL 
        AND  IUD.UNIT_DEF_ID = 'LU' 
        AND  IC.STORER_ID = 'PG' 
        AND  ICL.PHYSIC_QTY > 0 
        AND  I.ITEM_DESC LIKE '#%' 
        AND  I.ITEM_GROUP_ID IN ('BABYCARE','FEMCARE') 
    )AS BLOCKED_B2_PALLETS, 
    (SELECT COUNT(DISTINCT ICL.LUID_NO) 
      FROM  L2000.ITEM_CARRIER IC 
      INNER JOIN L2000.ITEM_UNITS_DEFINITION IUD ON IUD.PV_ID=IC.PV_ID AND IUD.STORER_ID=IC.STORER_ID AND IUD.ITEM_ID=IC.ITEM_ID 
      INNER JOIN L2000.ITEM_CARRIER_LUID ICL ON ICL.ITEM_CARRIER_NO=IC.ITEM_CARRIER_NO 
      INNER JOIN L2000.ITEM_PROPERTY IP ON IC.PROPERTY_INDEX=IP.PROPERTY_INDEX 
      INNER JOIN L2000.ITEM I ON I.ITEM_ID = IC.ITEM_ID AND I.STORER_ID = IC.STORER_ID 
        WHERE IC.PV_ID = 'B3' 
        AND  IP.BLOCK_CODE IS NOT NULL 
        AND  IUD.UNIT_DEF_ID = 'LU' 
        AND  IC.STORER_ID = 'PG' 
        AND  ICL.PHYSIC_QTY > 0 
        AND  I.ITEM_DESC LIKE '#%' 
        AND  I.ITEM_GROUP_ID IN ('BABYCARE','FEMCARE') 
    )AS BLOCKED_B3_PALLETS 

FROM L2000.ITEM_CARRIER 
WHERE ROWNUM = 1 
+0

Passer les sous-requêtes, faites une jointure gauche à la place. Et utilisez des expressions de cas pour effectuer une agrégation conditionnelle. – jarlh

+0

Vos sous-requêtes ne sont pas liées à la requête principale, donc au lieu de 'FROM L2000.ITEM_CARRIER WHERE ROWNUM = 1' vous pouvez tout aussi bien mettre' FROM DUAL' pour commencer. –

+0

Vous joignez 'ITEM' et' ITEM_CARRIER' et 'ITEM_UNITS_DEFINITION' sur' ITEM_ID'. Pourquoi pas "ITEM_PROPERTY" aussi? Cette table n'a-t-elle pas un 'ITEM_ID'? Cela aiderait si vous montriez et expliquiez comment les tables sont liées. Qu'est-ce qu'un 'PV_ID' par exemple? –

Répondre

3

Utiliser l'agrégation conditionnelle

SELECT COUNT(DISTINCT CASE WHEN IC.PV_ID = 'B2' 
       AND  IP.BLOCK_CODE IS NULL THEN ICL.LUID_NO END) AS B2_PALLETS, 
     COUNT(DISTINCT CASE WHEN IC.PV_ID = 'B3' 
       AND  IP.BLOCK_CODE IS NULL THEN ICL.LUID_NO END) AS B3_PALLETS, 
     COUNT(DISTINCT CASE WHEN IC.PV_ID = 'B2' 
       AND  IP.BLOCK_CODE IS NOT NULL THEN ICL.LUID_NO END) AS BLOCKED_B2_PALLETS, 
     COUNT(DISTINCT CASE WHEN IC.PV_ID = 'B3' 
       AND  IP.BLOCK_CODE IS NOT NULL THEN ICL.LUID_NO END) AS BLOCKED_B3_PALLETS 
     FROM  L2000.ITEM_CARRIER IC 
     INNER JOIN L2000.ITEM_UNITS_DEFINITION IUD ON IUD.PV_ID=IC.PV_ID AND IUD.STORER_ID=IC.STORER_ID AND IUD.ITEM_ID=IC.ITEM_ID 
     INNER JOIN L2000.ITEM_CARRIER_LUID ICL ON ICL.ITEM_CARRIER_NO=IC.ITEM_CARRIER_NO 
     INNER JOIN L2000.ITEM_PROPERTY IP ON IC.PROPERTY_INDEX=IP.PROPERTY_INDEX 
     INNER JOIN L2000.ITEM I ON I.ITEM_ID = IC.ITEM_ID AND I.STORER_ID = IC.STORER_ID 
       WHERE IUD.UOM_QTY = ICL.PHYSIC_QTY 
       AND  IUD.UNIT_DEF_ID = 'LU' 
       AND  IC.STORER_ID = 'PG' 
       AND  ICL.PHYSIC_QTY > 0 
       AND  I.ITEM_DESC LIKE '#%' 
       AND  I.ITEM_GROUP_ID IN ('BABYCARE','FEMCARE') 
+0

Cela semble à peu près correct, mais j'ai une "expression manquante" en cours d'exécution. Ne peut pas sembler trouver l'erreur que je suppose est une virgule supplémentaire ou quelque chose de similaire? –

+0

@ChristofferTrabjerg J'ai eu une virgule supplémentaire. Essayez-le maintenant. –

+0

J'ai beaucoup travaillé, j'ai trouvé la virgule aussi. Merci!! –