2010-07-21 9 views
10

Estoy usando Oracle SQL y quiero agrupar algunas filas diferentes que dan como resultado resultados de 'me gusta'. Elaborar con un ejemplo:SQL: ¿Es posible 'agrupar por' según los resultados de la función 'me gusta'?


Supongamos que tengo una tabla de Mesa con una de las columnas es una cadena enorme. Y estoy contando el número de filas que coincidan con patrones particulares:

SELECT m.str, count(*) 
FROM MESA m 
WHERE m.str LIKE '%FRUIT%' 
AND (m.str LIKE '%APPLE%' OR m.str LIKE '%ORANGE%') 

así que vamos a suponer que el resultado de esta consulta es:

FRUIT..afsafafasfa ... RED_APPLE 20

FRUTA ..afsafafasfa ... YELLOW_APPLE 12

FRUIT..afsafafasfa ... GREEN_APPLE 3

... FRUIT..afsafafasfa PURPLE_ORANGE 4

FRUIT..afsafafasfa ... RED_ORANGE 45

Pero yo quiero que mis resultados sean:

MANZANA 35

NARANJA 49


¿Es esto posible? Si es así, ¿cómo es eso? :)

Los comentarios y los fragmentos de código son muy apreciados.

PD: Por supuesto, la consulta y los resultados son más complicados que el ejemplo anterior. Simplemente lo escribí como por simplicidad para explicarlo.

Saludos ..

+2

¿Qué tal cadenas como esa: 'FRUIT..afsafafasfa ... ORANGE_APPLE "?;) – ThinkJet

+0

Sí, es un buen comentario. Para mi caso, no es muy probable que tenga tales cadenas. Supongo que depende del orden de los casos. – someone

Respuesta

11

Claro:

WITH Fruits AS (
    SELECT 
     CASE 
      WHEN m.str LIKE '%APPLE%' THEN 'Apple' 
      WHEN m.str LIKE '%ORANGE%' THEN 'Orange' 
     END AS FruitType   
    FROM MESA m 
    WHERE m.str LIKE '%FRUIT%') 
SELECT FruitType, COUNT(*) 
FROM Fruits 
WHERE FruitType IN ('Apple', 'Orange') 
GROUP BY FruitType; 
+1

Ok, funciona, +1 – ThinkJet

+0

Gracias Dave. Me encanta esto WITH thingie:) – someone

0
SELECT count(*) AS 'Apples' 
FROM MESA m 
WHERE m.str LIKE '%FRUIT%' 
AND m.str LIKE '%APPLE%' 

SELECT count(*) AS 'Oranges' 
FROM MESA m 
WHERE m.str LIKE '%FRUIT%' 
AND m.str LIKE '%ORANGE%' 

¿Funcionaría?

+0

Gracias por la respuesta JNKyle. También he pensado en esto, pero la respuesta de Dave es más apropiada para mi caso (ya que tengo muchos grupos para hacer) – someone

0

Algo como esto?

SELECT Fruit, 
     SUM(counter) 
FROM (SELECT CASE 
        WHEN m.str LIKE '%APPLE%' 
         THEN 'APPLE' 
        ELSE 'ORANGE' 
       END AS Fruit 
       COUNT(*) AS counter 
      FROM MESA m 
     WHERE m.str LIKE '%FRUIT%' 
      AND (m.str LIKE '%APPLE%' OR m.str LIKE '%ORANGE%') 
     GROUP BY m.str 
    ) 
GROUP BY Fruit 
+0

no puedes usar count (*) sin cláusula de agrupación ... (mira la selección interna) – ThinkJet

+0

Gracias por la respuesta Mark. – someone

+0

@ ThinkJet- Lo siento, pensé que tenía un GROUP BY en el SELECT interno –

2

Otra variante de David Markle respuesta:

SELECT 
    fruit_name, 
    count(1) as fruit_count 
FROM (
    SELECT 
    CASE 
     WHEN m.str LIKE '%APPLE%' THEN 'Apple' 
     WHEN m.str LIKE '%ORANGE%' THEN 'Orange' 
    END           as fruit_name 
    FROM 
    MESA m 
    WHERE 
    m.str LIKE '%FRUIT%' 
    AND 
    (m.str LIKE '%APPLE%' OR m.str LIKE '%ORANGE%') 
) 
GROUP BY 
    fruit_name 

lo mismo, pero sólo en 1 caso necesario, lo que simplifica el soporte ...

+0

Gracias por la respuesta ThinkJet. Muy apreciado. – someone

0

lo haría de esta manera - sólo requiere un solo cambio para agregar tipos adicionales de fruta.

WITH fruits AS (
    SELECT 'APPLE' fruit FROM DUAL 
    UNION ALL 
    SELECT 'ORANGE' fruit FROM DUAL 
) 
SELECT fruit, count(*) 
FROM MESA m, fruits 
WHERE m.str LIKE '%FRUIT%' 
AND m.str LIKE '%' || fruits.fruit || '%' 
GROUP BY fruit 

Si las cadenas son de forma fiable en el formato que demuestran en sus datos de ejemplo, yo estaría dispuesto a cambiar el predicado de una condición, WHERE m.str LIKE 'FRUIT%' || fruits.fruit ||'%'.

Cuestiones relacionadas