¿Qué es una instrucción SQL para seleccionar un elemento que tiene varios atributos en una lista de elementos / atributos?
-
06-09-2019 - |
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?
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.