Necesito recuperar todas las filas de una tabla donde 2 columnas combinadas son todas diferentes. Así que quiero todas las ventas que no tienen otras ventas que ocurrieron 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.
Entonces estoy pensando:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Pero me duele el cerebro ir más allá de eso.
sql
postgresql
sql-update
duplicates
distinct
fundas
fuente
fuente
Si reúne las respuestas hasta ahora, limpia y mejora, llegaría a esta consulta superior:
Cual 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
NOT EXISTS
(anti) semiunión para un rendimiento aún mejor.EXISTS
es 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:db <> violín aquí
Viejo violín de SQL
Clave única para identificar fila
Si no tiene una clave primaria o única para la tabla (
id
en el ejemplo), puede sustituirla con la columna del sistemactid
para el propósito de esta consulta (pero no para otros fines):Cada tabla debe tener una clave primaria. Agregue uno si aún no tiene uno. Sugiero un
serial
o unaIDENTITY
columna en Postgres 10+.Relacionado:
¿Cómo es esto más rápido?
La subconsulta en el
EXISTS
anti-semi-join puede dejar de evaluar tan pronto como se encuentre el primer engañado (no tiene sentido buscar más). Para una tabla base con pocos duplicados, esto es solo un poco más eficiente. Con muchos duplicados esto se convierte en camino más eficiente.Excluir actualizaciones vacías
Para las filas que ya tienen
status = 'ACTIVE'
esta actualización, no cambiaría nada, pero aún así se inserta una nueva versión de la fila al costo total (se aplican excepciones menores). Normalmente, no quieres esto. Agregue otraWHERE
condición como se demostró anteriormente para evitar esto y hacerlo aún más rápido:Si
status
está definidoNOT NULL
, puede simplificarlo para:El tipo de datos de la columna debe ser compatible con el
<>
operador. Algunos tiposjson
no lo hacen. Ver:Diferencia sutil en el manejo NULL
Esta consulta (a diferencia de la respuesta aceptada actualmente por Joel ) no trata los valores NULL como iguales. Las siguientes dos filas
(saleprice, saledate)
calificarían como "distintas" (aunque parezcan idénticas al ojo humano):También pasa un índice único y casi en cualquier otro lugar, ya que los valores NULL no se comparan igual de acuerdo con el estándar SQL. Ver:
Otoh,
GROUP BY
,DISTINCT
oDISTINCT ON ()
valores treat NULL como iguales. Use un estilo de consulta apropiado según lo que quiera lograr. Todavía puede usar esta consulta más rápida con enIS NOT DISTINCT FROM
lugar de=
cualquiera o todas las comparaciones para hacer que la comparación NULL sea igual. Más:Si se definen todas las columnas que se comparan
NOT NULL
, no hay lugar para el desacuerdo.fuente
count(*)
es más eficiente quecount(<expression>)
. Solo inténtalo. Postgres tiene una implementación más rápida para esta variante de la función agregada. ¿Quizás estás confundiendo Postgres con algún otro RDBMS?El problema con su consulta es que cuando usa una cláusula GROUP BY (que esencialmente hace al usar distintivo) solo puede usar columnas por las que agrupa o agrega 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.
Sin embargo, esto debería funcionar (y no necesita una combinación):
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.
fuente
Quiero seleccionar los valores distintos de una columna 'GrondOfLucht' pero deben clasificarse en el orden que figura en la columna 'clasificación'. No puedo obtener los valores distintos de una sola columna usando
También le dará a la columna 'clasificación' y debido a que 'GrondOfLucht' Y 'clasificación' no es única, el resultado será TODAS las filas.
use el GRUPO para seleccionar los registros de 'GrondOfLucht' en el orden dado por 'clasificación
fuente
Si su DBMS no es compatible con varias columnas como esta:
La selección múltiple en general se puede ejecutar de forma segura de la siguiente manera:
Como esto puede funcionar en la mayoría de los DBMS y se espera que sea más rápido que agrupar por solución, ya que está evitando la funcionalidad de agrupación.
fuente