una transponer tablas tabla obtener listar las filas estructura ejemplo datos convertir columnas sql postgresql sql-update duplicates distinct

tablas - transponer filas en columnas mysql



¿Cómo puedo(o puedo) SELECCIONAR DISTINCIÓN en varias columnas? (4)

El problema con su consulta es que cuando usa una cláusula GROUP BY (lo que básicamente hace usando distintas), solo puede usar columnas que agrupe o agregue funciones. No puede usar el ID de columna porque hay valores potencialmente diferentes. En su caso, siempre hay un solo valor debido a la cláusula HAVING, pero la mayoría de los RDBMS no son lo suficientemente inteligentes como para reconocerlo.

Esto debería funcionar sin embargo (y no necesita una combinación):

UPDATE sales SET status=''ACTIVE'' WHERE id IN ( SELECT MIN(id) FROM sales GROUP BY saleprice, saledate HAVING COUNT(id) = 1 )

También puede usar MAX o AVG en lugar de MIN, solo es importante usar una función que devuelva el valor de la columna si solo hay una fila coincidente.

Necesito recuperar todas las filas de una tabla donde 2 columnas combinadas son todas diferentes. Así que quiero todas las ventas que no tengan ninguna otra venta que haya tenido lugar el mismo día por el mismo precio. Las ventas que son únicas según el día y el precio se actualizarán a un estado activo.

Así que estoy pensando:

UPDATE sales SET status = ''ACTIVE'' WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id) FROM sales HAVING count = 1)

Pero mi cerebro duele yendo más allá de eso.


Quiero seleccionar los valores distintos de una columna ''GrondOfLucht'', pero deberían ordenarse en el orden que se indica en la columna ''clasificación''. No puedo obtener los valores distintos de una sola columna usando

Select distinct GrondOfLucht,sortering from CorWijzeVanAanleg order by sortering

También le dará a la columna "clasificación" y como "GrondOfLucht" Y "clasificación" no son únicos, el resultado serán TODAS las filas.

Use el GRUPO para seleccionar los registros de ''GrondOfLucht'' en el orden dado por ''clasificador

SELECT GrondOfLucht FROM dbo.CorWijzeVanAanleg GROUP BY GrondOfLucht, sortering ORDER BY MIN(sortering)


Si reúne las respuestas hasta el momento, limpie y mejore, llegará a esta consulta superior:

UPDATE sales SET status = ''ACTIVE'' WHERE (saleprice, saledate) IN ( SELECT saleprice, saledate FROM sales GROUP BY saleprice, saledate HAVING count(*) = 1 );

Que es mucho más rápido que cualquiera de ellos. Nukes el rendimiento de la respuesta actualmente aceptada por el factor 10 - 15 (en mis pruebas en PostgreSQL 8.4 y 9.1).

Pero esto aún está lejos de ser óptimo. Utilice una semi-unión NOT EXISTS (anti) para obtener un rendimiento aún mejor. EXISTS es un SQL estándar, ha existido desde siempre (al menos desde PostgreSQL 7.2, mucho antes de que se hiciera esta pregunta) y se ajusta perfectamente a los requisitos presentados:

UPDATE sales s SET status = ''ACTIVE'' WHERE NOT EXISTS ( SELECT 1 FROM sales s1 WHERE s.saleprice = s1.saleprice AND s.saledate = s1.saledate AND s.id <> s1.id -- except for row itself ); AND s.status IS DISTINCT FROM ''ACTIVE''; -- avoid empty updates. see below

El violín de SQL.

Clave única para identificar la fila

Si no tiene una clave principal o única para la tabla ( id en el ejemplo), puede sustituirla con la columna del sistema ctid para el propósito de esta consulta (pero no para otros propósitos):

AND s1.ctid <> s.ctid

Cada tabla debe tener una clave primaria. Agrega uno si aún no tienes uno. Sugiero una columna de serial o IDENTITY en Postgres 10+.

Relacionado:

¿Cómo es esto más rápido?

La subconsulta en la anti-semi-unión EXISTS puede dejar de evaluar tan pronto como se encuentre la primera duplicidad (no tiene sentido mirar más allá). Para una tabla base con pocos duplicados, esto es solo ligeramente más eficiente. Con muchos duplicados esto se vuelve mucho más eficiente.

Excluir actualizaciones vacías

Si algunas o muchas filas ya tienen el status = ''ACTIVE'' , su actualización no cambiará nada, pero aún así insertará una nueva versión de la fila a un costo total (se aplican excepciones menores). Normalmente, no quieres esto. Agregue otra condición WHERE como se demostró anteriormente para hacer esto aún más rápido:

Si el status se define como NOT NULL , puede simplificar a:

AND status <> ''ACTIVE'';

Diferencia sutil en el manejo NULL

Esta consulta (a diferencia de la respuesta actualmente aceptada por Joel ) no trata los valores NULL como iguales. Estas dos filas para (saleprice, saledate) calificarían como "distintas" (aunque parecen idénticas al ojo humano):

(123, NULL) (123, NULL)

También pasa en un índice único y casi en cualquier otro lugar, ya que los valores NULL no se comparan de acuerdo con el estándar SQL. Ver:

OTOH, GROUP BY o DISTINCT o DISTINCT ON () tratan los valores NULL como iguales. Utilice un estilo de consulta adecuado en función de lo que desea lograr. Aún puede usar este estilo de consulta más rápido usando IS NOT DISTINCT FROM lugar de = para cualquiera o todas las comparaciones para hacer que NULL compare igual. Más:

Si todas las columnas que se comparan están definidas como NOT NULL , no hay espacio para el desacuerdo.


SELECT DISTINCT a,b,c FROM t

es aproximadamente equivalente a:

SELECT a,b,c FROM t GROUP BY a,b,c

Es una buena idea acostumbrarse a la sintaxis de GROUP BY, ya que es más potente.

Para tu consulta, lo haría así:

UPDATE sales SET status=''ACTIVE'' WHERE id IN ( SELECT id FROM sales S INNER JOIN ( SELECT saleprice, saledate FROM sales GROUP BY saleprice, saledate HAVING COUNT(*) = 1 ) T ON S.saleprice=T.saleprice AND s.saledate=T.saledate )