¿Qué es una instrucción SQL para seleccionar un elemento que tiene varios atributos en una lista de elementos / atributos?

StackOverflow https://stackoverflow.com/questions/927724

Pregunta

Decir que tengo una tabla que tiene los elementos y atributos que figuran como,

frog    green
cat     furry
frog    nice
cat     4 legs
frog    4 legs

En la columna Elementos Quiero seleccionar objetos únicos que tienen el atributo verde y 4 patas. Yo esperaría que volver sólo el objeto rana en este caso. ¿Cuál es la consulta más eficiente de hacer esto?

¿Fue útil?

Solución

select  item.name 
from    item 
where   item.attribute in ('4 legs', 'green') 
group by item.name 
having  count(distinct item.attribute) = 2

Otros consejos

La forma más eficaz de hacerlo es con un auto-join:

SELECT * FROM attributes a1 
JOIN attributes a2 USING (item_name) -- e.g. frog
WHERE a1.value = 'green' AND a2.value = '4 legs';

Otra solución que utilizan algunas personas es un truco con GROUP BY:

SELECT item_name FROM attributes
WHERE value IN ('4 legs', 'green')
GROUP BY item_name
HAVING COUNT(*) = 2;

Pero el GROUP BY solución puede no ser tan eficiente como una combinación, dependiendo de la marca de RDBMS que utiliza. También un método puede escalar mejor, ya que el volumen crece en su mesa.

SELECT * FROM tabla en la que = 'rana'

nada mejor que saber exactamente lo que quiere.

select
    item, count(*)
from
    @temp
where
    attribute in ('4 legs','green')
group by
    item
having
    count(*) = 2 -- this "2" needs to be replaced with however many attributes you have

También puede consultar cada atributo por separado, y luego se cruzan ellos ...

/*
-- create sample table...
create table #temp1
    (item varchar(max),
    attrib varchar(max))

-- populate sample table (SQL 08)...
insert #temp1
values ('frog', 'green'), ('cat', 'furry'), ('frog', 'nice'), ('cat', '4 legs'), ('frog', '4 legs')
*/


SELECT  item
FROM    #temp1
WHERE   attrib = 'green'
INTERSECT
SELECT  item
FROM    #temp1
WHERE   attrib = '4 legs'

crear dos tablas, una de artículos y uno de los atributos.
Los artículos se podían nombrar, intAttributeID, donde intAttributeID es una referencia clave externa a la tabla de atributos. De esa manera usted puede hacer una declaración de selección basa fuera todo lo que importa.

Pero tal vez esto puede ayudar a:

SELECT * 
FROM tbl t1
INNER JOIN tbl t2 ON t1.Name = t2.Name
WHERE t1.Attribute = 'green' AND t2.Attribute = '4 legs'

duro, porque no es un modelo normalizado. Es un fin de semana.

Se está filtrando a través de múltiples filas sin conexión, por lo que tendría que extraer cada atributo a su vez y luego igualar artículos.

SELECT
   item
FROM
    (SELECT
        item
    FROM
        Mytable
    WHERE
        attribute = '4 legs') k1
    JOIN
    (SELECT
        item
    FROM
        Mytable
    WHERE
        attribute = 'green') k2 ON k1.item = k2.item

Si es posible, me gustaría rediseñar. Esto no es algo que tendrá que ser capaz de consultar de manera efectiva en 12 valores al mismo tiempo en (se requerirá 12 se une a)

Por favor, lea este artículo de Wikipedia http://en.wikipedia.org/wiki/Entity-Attribute-Value_model# Los inconvenientes

Nunca visto una base de datos todavía que utiliza este modelo que no tenga problemas graves de rendimiento con el tiempo. Este diseño se ve elegante a personas que no son de base de datos, pero en realidad es generalmente un signo de una base de datos mal diseñada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top