¿Cómo puedo devolver resultados de SQL que SOLO se refieren a atributos específicos?

Tengo una tabla similar a la siguiente:

REL_Aid_To_AttributeValue:
ID    AttributeValueID
101   1319
101   1320
101   1344
101   1345
102   1319
102   1320
102   1321
102   1336
103   1320
103   1336

Tengo otra tabla que agrupa estos AttributeValueID por tipo:

TBL_AttributeValues:
AttributeValueID    AttributeTypeID
1319                1
1320                1
1321                1
1336                2
1344                3 
1345                3

Tengo una tercera tabla que brinda información sobre cada ID de la primera tabla:

TBL_Aids:
ID     Title                Author       etc.
101    Aid About Spiders    John Doe
102    Aid About Mites      Jane Doe 
103    Aid About Beetles    Joe Schmo

Me gustaría devolver los resultados de los ID (e información sobre ellos, como el título, el autor, etc.) que contienen SOLO AttributeValueIDs 1319 O (inclusive) 1320, dentro de AttributeTypeID=1. Entonces espero devolver 101 porque solo tiene 1319 y 1320 para AttributeType 1, y también 103 porque solo tiene 1320 para AttributeType 1. No quisiera devolver 102 porque aunque tiene 1319 y 1320, también tiene 1321, que también es de AttributeType 1.

He probado lo siguiente:

SELECT a.ID, a.Title, c.AttributeTypeID, 
COUNT(b.AttributeValueID)AS Total
FROM TBL_Aids as a,
REL_Aid_To_AttributeValue as b,
TBL_AttributeValues as c
WHERE a.ID=b.AidID
AND b.AttributeValueID=c.ID
AND a.Status=2
AND AttributeTypeID=1
AND (b.AttributeValueID=1319
OR b.AttributeValueID=1320)
GROUP BY a.ID, a.Title,
c.AttributeTypeID
HAVING COUNT(b.AttributeValueID) <= 2 

Pero aún devuelve 102 como resultado, porque ya está limitado por 1319 y 1320 y está contando ese total en lugar del total general de AttributeValueID para el Tipo 1. ¿Necesito algún tipo de subconsulta para lograr esto? ¡Cualquier ayuda sería apreciada! Muchas gracias.

preguntado el 22 de mayo de 12 a las 20:05

7 Respuestas

Tratar:

SELECT DISTINCT A.ID
FROM REL_Aid_To_AttributeValue A
WHERE A.AttributeValueID IN
(
    SELECT AttributeValueID
    FROM TBL_AttributeValues
    WHERE AttributeValueID IN (1319, 1320) AND AttributeTypeID=1
)
AND A.ID NOT IN
(
    SELECT A.ID
    FROM REL_Aid_To_AttributeValue A
    WHERE A.AttributeValueID IN
    (
        SELECT AttributeValueID
        FROM TBL_AttributeValues
        WHERE AttributeValueID NOT IN (1319, 1320)  AND AttributeTypeID=1
    )
)

contestado el 23 de mayo de 12 a las 19:05

No debo haber explicado muy bien esa parte, lo siento. Debería haber explicado la tercera tabla y haberla etiquetado, ya que ahora están en mis ediciones anteriores. "WHERE A.AttributeValueID IN" no es correcto porque AttributeValueID no está en TBL_Aids. Además, AttributeTypeID no está en AttributeValueIDs. - monalisa717

SELECT  id
FROM    (
        SELECT  DISTINCT id
        FROM    REL_Aid_To_AttributeValue a
        WHERE   attributeValueId IN (1319, 1320)
        ) q
WHERE   NOT EXISTS
        (
        SELECT  id
        FROM    (
                SELECT  AttributeValueID
                FROM    TBL_AttributeValues
                WHERE   AttributeTypeID = 1
                        AND AttributeValueID NOT IN (1319, 1320)
                ) t
        JOIN    REL_Aid_To_AttributeValue a
        ON      a.id = q.id
                AND a.AttributeValueID = t.AttributeValueID
        )

contestado el 22 de mayo de 12 a las 21:05

Esto es brillante. Muchas gracias. Terminé agregando a esto para obtener la información final que quería, pero nunca podría haberlo hecho sin su ayuda. ¡Gracias de nuevo! - monalisa717

Debe unirse a REL_Aid_To_AttributeValue dos veces para asegurarse de que dos existen filas

SELECT a.ID, a.Title, c.AttributeTypeID, 2 AS Total
FROM TBL_Aids a
join REL_Aid_To_AttributeValue b on a.ID=b.AidID and b.AttributeValueID = 1319
join REL_Aid_To_AttributeValue b2 on a.ID=b2.AidID and b2.AttributeValueID = 1320
join TBL_AttributeValues c on b.AttributeValueID=c.ID
WHERE a.Status=2
AND AttributeTypeID=1;

Tampoco es que si sabes qué valores tienes, sabes cuántos hay, así que es un literal 2.

contestado el 22 de mayo de 12 a las 21:05

Debe unirse a REL_Aid_To_AttributeValue dos veces para asegurarse de que dos existen filas

SELECT a.ID, a.Title, c.AttributeTypeID, 2 AS Total
FROM TBL_Aids a
join REL_Aid_To_AttributeValue b on a.ID=b.AidID and b.AttributeValueID = 1319
join REL_Aid_To_AttributeValue b2 on a.ID=b2.AidID and b2.AttributeValueID = 1320
join TBL_AttributeValues c on b.AttributeValueID=c.ID
WHERE a.Status=2
AND AttributeTypeID=1;

Tenga en cuenta que he convertido su consulta a la sintaxis de "unión" más moderna. Te sugiero que lo aprendas.

También tenga en cuenta que si sabe qué valores tiene, sabe cuántos hay, por lo que es un literal 2.

contestado el 22 de mayo de 12 a las 21:05

Esto no es del todo correcto, pero parecía tener sentido para mí. Solo arroja alrededor de 100 resultados, pero calculo que el conjunto de resultados está más cerca de 700. Además, y lo que es más importante, los resultados son inexactos. Tienen los valores de atributo 1319 y 1320, pero también tienen otros valores de atributo. Sí, no he usado join mucho porque no vi el beneficio de la forma en que lo usé. Si funcionara en este caso, ¡estaría convencido! Gracias por tu sugerencia. - monalisa717

Desea limitar sus identificaciones. En algún lugar de su cláusula where, puede incluir algo como:

where id in (select distinct av.id
             from AttributeValueType avt join
                  AttributeValue av
                   on avt.AttributeValueId = av.AttributeValueId
             where avt.AttributeValueId in (1319, 1320) and avt.AttributeTypeID = 1
            )

Si solo quiere cuando esos dos atributos están allí, intente esto:

Where id in (
    Select av.id
    From AttributeValueType avt join
         AttributeValue av
         on avt.AttributeValueId = av.AttributeValueId
    Group by av.id
    Having max(case when avt.AttributeValueId in (1319, 1320) and avt.AttributeTypeID = 1 then 0 else 1)=0
    Having max(case when 

contestado el 23 de mayo de 12 a las 03:05

Ejecutar esta subconsulta por sí sola devuelve resultados que tienen otros AttributeValueID distintos de 1319 y 1320 (que todavía son de AttributeValueTypeID = 1). ¿Debería estar pasando eso? - monalisa717

Gorrón. Parecía una buena idea, pero está devolviendo 0 resultados. ¡Gracias por intentarlo de nuevo! - monalisa717

Creo que necesitas agregar 'NO EXISTE' de alguna manera:

SELECT DISTINCT ID
FROM TBL_Aids x
WHERE AttributeValueID IN
(
    SELECT AttributeValueID
    FROM AttributeValueIDs
    WHERE AttributeValueID IN (1319, 1320) AND AttributeTypeID=1
) AND NOT EXISTS
(
    SELECT *
    FROM AttributeValueIDs a
    WHERE a.AttributeValueID NOT IN (1319, 1320) AND a.AttributeTypeID=1
    AND a.AttributeValueIDs = x.AttributeValueIDs
)

contestado el 23 de mayo de 12 a las 05:05

"No existe" parece una buena idea, pero todavía estoy confundido sobre cómo funcionaría esto. Creo que AttributeValueID debe seleccionarse de REL_Aid_To_AttributeValue, mientras que AttributeTypeID solo está en TBL_AttributeValues. ¿No sería necesario que hubiera otras uniones aquí para relacionar los dos? - monalisa717

Funcionaría porque rechazaría las filas donde AttributeTypeID es del tipo dado pero AttributeValueID no de la lista dada. - Thomas Mueller

Lo siento, debería haberlo explicado mejor. Edité mi pregunta anterior para incluir la otra tabla de la que necesito obtener información. AttributeValueID no está en TBL_Aids, y AttributeTypeID no está en lo que llamaste AttributeValueIDs (supuse que te referías a REL_Aid_To_AttributeValue?) - monalisa717

No hay problema. Traté de editar la respuesta para usar los nombres de tabla correctos, pero luego se volvió demasiado complicado para mí. Quassnoi lo hizo bien. - Thomas Mueller

Gracias a Quassnoi:

    SELECT ID, Title, Author
    FROM TBL_Aids X
    JOIN (
    SELECT AidID
    FROM    (
            SELECT  DISTINCT AidID
            FROM    REL_Aid_To_AttributeValue a
            WHERE   AttributeValueID IN (1319, 1320)
            ) q
    WHERE   NOT EXISTS
            (
            SELECT  AidID
            FROM    (
                    SELECT  ID
                    FROM    TBL_AttributeValues
                    WHERE   AttributeTypeID = 1
                            AND ID NOT IN (1319, 1320)
                    ) t
            JOIN    REL_Aid_To_AttributeValue a
            ON      a.AidID = q.AidID
                    AND a.AttributeValueID = t.ID
            ))
    Y ON X.ID=Y.AidID
    WHERE Status=2

contestado el 23 de mayo de 12 a las 19:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.