ventajas market español sql mysql sql-server database postgresql

market - sql server 2017 vs postgresql 10



Seleccionar filas únicas en un conjunto de dos posibilidades (9)

El problema en sí es simple, pero no puedo encontrar una solución que lo haga en una consulta, y aquí está mi "abstracción" del problema para permitir una explicación más simple:

Dejaré mi stand original, pero aquí hay un conjunto de datos de muestra y el resultado que espero:

Bien, entonces aquí hay algunos datos de muestra, separé pares por una línea en blanco

------------- | Key | Col | (Together they from a Unique Pair) -------------- | 1 Foo | | 1 Bar | | | | 2 Foo | | | | 3 Bar | | | | 4 Foo | | 4 Bar | --------------

Y el resultado que esperaría, después de ejecutar la consulta una vez , debe ser capaz de seleccionar este conjunto de resultados en una consulta:

1 - Foo 2 - Foo 3 - Bar 4 - Foo

Explenation original:

Tengo una tabla, llámala TABLE donde tengo dos columnas, dicen ID y NAME que juntas forman la clave principal de la tabla. Ahora quiero seleccionar algo donde ID=1 y luego primero compruebo si puede encontrar una fila donde NAME tenga el valor "John", si "John" no existe debería buscar una fila donde NAME es "Bruce" - pero solo devuelve "John" si existen "Bruce" y "John" o solo existe "John", por supuesto.

También tenga en cuenta que debe poder devolver varias filas por consulta que coincidan con los criterios anteriores, pero con diferentes combinaciones de ID / Nombre, por supuesto, y que la explicación anterior sea solo una simplificación del problema real.

Podría estar completamente cegado por mi propio código y línea de pensamiento, pero no puedo resolver esto.


Bien, entonces aquí hay algunos datos de muestra, separé pares por una línea en blanco

------------- | Key | Col | (Together they from a Unique Pair) -------------- | 1 Foo | | 1 Bar | | | | 2 Foo | | | | 3 Bar | | | | 4 Foo | | 4 Bar | --------------

Y el resultado que esperaría:

1 - Foo 2 - Foo 3 - Bar 4 - Foo

Lo resolví anteriormente, pero esa pregunta es terriblemente ineficiente para las mesas de lager, de otra manera?


En PostgreSQL, creo que sería esto:

SELECT DISTINCT ON (id) id, name FROM mytable ORDER BY id, name = ''John'' DESC;

Actualización - falso tipo antes verdadero - Lo tenía al revés originalmente. Tenga en cuenta que DISTINCT ON es una función de PostgreSQL y no parte de SQL estándar. Lo que sucede aquí es que solo muestra la primera fila para cualquier ID dado que se encuentre. Ya que ordenamos por clima el nombre es John, las filas nombradas John se seleccionarán sobre todos los demás nombres.

Con su segundo ejemplo, sería:

SELECT DISTINCT ON (key) key, col FROM mytable ORDER BY key, col = ''Foo'' DESC;

Esto te dará:

1 - Foo 2 - Foo 3 - Bar 4 - Foo


Esto es bastante similar a lo que escribió, pero debe ser bastante rápido ya que NOT EXISTS es más eficiente, en este caso, que NOT IN ...

mysql> select * from foo; +----+-----+ | id | col | +----+-----+ | 1 | Bar | | 1 | Foo | | 2 | Foo | | 3 | Bar | | 4 | Bar | | 4 | Foo | +----+-----+ SELECT id , col FROM foo f1 WHERE col = ''Foo'' OR ( col = ''Bar'' AND NOT EXISTS( SELECT * FROM foo f2 WHERE f1.id = f2.id AND f2.col = ''Foo'' ) ); +----+-----+ | id | col | +----+-----+ | 1 | Foo | | 2 | Foo | | 3 | Bar | | 4 | Foo | +----+-----+


Puede usar uniones en lugar del existente y esto puede mejorar el plan de consulta en los casos en que el optimizador no sea lo suficientemente inteligente:

SELECT f1.id ,f1.col FROM foo f1 LEFT JOIN foo f2 ON f1.id = f2.id AND f2.col = ''Foo'' WHERE f1.col = ''Foo'' OR ( f1.col = ''Bar'' AND f2.id IS NULL )


Se me ocurrió una solución, pero es algo compleja y lenta, y tampoco se amplía a consultas más avanzadas:

SELECT * FROM users WHERE name = "bruce" OR ( name = "john" AND NOT id IN ( SELECT id FROM posts WHERE name = "bruce" ) )

Sin alternativas sin uniones pesadas, etc.?


prueba esto:

select top 1 * from ( SELECT 1 as num, * FROM TABLE WHERE ID = 1 AND NAME = ''John'' union SELECT 2 as num, * FROM TABLE WHERE ID = 1 AND NAME = ''Bruce'' ) t order by num


Aquí hay un ejemplo que funciona en SQL Server 2005 y versiones posteriores. Es un patrón útil en el que desea elegir la fila superior (o las primeras n filas) según un pedido personalizado. Esto le permitirá no solo elegir entre dos valores con prioridades personalizadas, sino cualquier número. Puede usar la función ROW_NUMBER () y una expresión CASE:

CREATE TABLE T (id int, col varchar(10)); INSERT T VALUES (1, ''Foo'') INSERT T VALUES (1, ''Bar'') INSERT T VALUES (2, ''Foo'') INSERT T VALUES (3, ''Bar'') INSERT T VALUES (4, ''Foo'') INSERT T VALUES (4, ''Bar'') SELECT id,col FROM (SELECT id, col, ROW_NUMBER() OVER ( PARTITION BY id ORDER BY CASE col WHEN ''Foo'' THEN 1 WHEN ''Bar'' THEN 2 ELSE 3 END ) AS RowNum FROM T ) AS X WHERE RowNum = 1 ORDER BY id


Puedes unirte a la tabla inicial con un OUTER JOIN como este:

create table #mytest ( id int, Name varchar(20) ); go insert into #mytest values (1,''Foo''); insert into #mytest values (1,''Bar''); insert into #mytest values (2,''Foo''); insert into #mytest values (3,''Bar''); insert into #mytest values (4,''Foo''); insert into #mytest values (4,''Bar''); go select distinct sc.id, isnull(fc.Name, sc.Name) sel_name from #mytest sc LEFT OUTER JOIN #mytest fc on (fc.id = sc.id and fc.Name = ''Foo'')

como eso.


No es necesario que sea demasiado complejo, solo puede usar MAX() y group by ...

select id, max(col) from foo group by id