es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo lidiar con el operador IN de SQL que devuelve múltiples valores cuando solo se necesita uno?

Estoy trabajando en una jerarquía de múltiples padres e hijos que se parece a esto. Este es un subconjunto de una tabla con 105k registros.

NodeKey ParentKey Child Parent
1 A
2 B
3 C A
4 D B
5 D C

Necesito llenar la columna ParentKey con datos con la siguiente condición.

Si el valor en Parent es NULL, también establezca el valor en ParentKey como NULL.

Si el valor en Parent es NOT NULL y también está en Child, entonces seleccione el NodeKey correspondiente y establezca como valor en ParentKey (ver segunda tabla).

Puedo hacer eso, pero hay un problema cuando el valor de la columna Parent aparece más de una vez en la columna Child.

En la quinta fila, no importa cuál valor se elija entre 3 o 4. Puede ser cualquiera.

NodeKey ParentKey Child Parent
1 A
2 B
3 1 C A
4 2 C B
5 No importa si es 3 o 4 D C
SELECT (CASE WHEN Parent IS NULL THEN NULL 

ELSE 

(SELECT NodeKey from table WHERE Parent IN (SELECT Child from table)) END) as ParentKey

Al ejecutar este código, me dice que “Subquery returned more that 1 value”, lo cual tiene sentido. Pero independientemente de dónde ponga un max() o min(), no funciona.

Cuando pongo max() delante de NodeKey, solo devuelve una columna llena de NULL y 105314. 105314 es la cantidad de filas en la tabla.

Estoy usando SQL Server Management Studio 17.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para manejar la situación en la que el valor de Padre aparece más de una vez en la columna Hijo, puedes utilizar la cláusula TOP 1 junto con la cláusula ORDER BY para seleccionar la primera clave de nodo coincidente. Esto se puede hacer modificando la subconsulta de la siguiente manera:

    (SELECT TOP 1 NodeKey FROM table WHERE Parent IN (SELECT Child from table) ORDER BY NodeKey) AS ParentKey
    

    Esto seleccionará la primera clave de nodo coincidente según el orden de NodeKey. Si desea elegir el valor mínimo o máximo de NodeKey en su lugar, puede reemplazar ORDER BY NodeKey con ORDER BY NodeKey ASC o ORDER BY NodeKey DESC, respectivamente.

    La consulta completa quedaría así:

    SELECT 
        CASE WHEN Parent IS NULL THEN NULL 
             ELSE (SELECT TOP 1 NodeKey FROM table WHERE Parent IN (SELECT Child from table) ORDER BY NodeKey) 
        END AS ParentKey,
        NodeKey, Child, Parent
    FROM table
    

Comments are closed.