Pregunta

Añadido: Trabajar con SQL Server 2000 y 2005, por lo que tiene que trabajar en ambos. Además, value_rk no es un número / entero (Error: el identificador único del tipo de datos del operando no es válido para el operador mínimo)

¿Hay alguna forma de hacer una sola columna " DISTINCT " ¿Coincide cuando no me importan las otras columnas devueltas? Ejemplo:

**Table**
Value A, Value L, Value P
Value A, Value Q, Value Z

Necesito devolver solo una de estas filas según lo que está en la primera (Valor A). Todavía necesito resultados de la segunda y tercera columnas (la segunda debería coincidir con todas las áreas de todos modos, pero la tercera es una clave única, que necesito al menos una).

Esto es lo que tengo hasta ahora, aunque obviamente no funciona:

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
WHERE value IN (
    SELECT value, max(value_rk)
    FROM attribute_values
)
ORDER BY attribute_definition_id

Estoy trabajando en ColdFusion, así que si hay una solución simple, también estoy abierto a eso. Estoy intentando limitar o " agrupar por " la primera columna " valor " ;. value_rk es mi gran problema ya que cada valor es único, pero solo necesito uno.

NOTA: value_rk no es un número, por lo tanto, esto NO FUNCIONA

ACTUALIZACIÓN: Tengo una versión que funciona, probablemente sea un poco más lenta que una versión SQL pura, pero honestamente, cualquier cosa que funcione en este punto es mejor que nada. Toma los resultados de la primera consulta, realiza una segunda consulta, excepto que limita los resultados a uno, y toma un valor_rk correspondiente para el valor que coincide. Al igual que:

<cfquery name="queryBaseValues" datasource="XXX" timeout="999">
    SELECT DISTINCT value, attribute_definition_id
    FROM attribute_values
    ORDER BY attribute_definition_id
</cfquery>

<cfoutput query="queryBaseValues">
    <cfquery name="queryRKValue" datasource="XXX">
        SELECT TOP 1 value_rk
        FROM attribute_values
        WHERE value = '#queryBaseValues.value#'
    </cfquery>
    <cfset resourceKey = queryRKValue.value_rk>
    ...

Así que ahí lo tienen, seleccionando una sola columna de forma distinta en ColdFusion. Cualquier sugerencia pura de SQL Server 2000/2005 es muy bienvenida :)

¿Fue útil?

Solución

esto podría funcionar:

SELECT DISTINCT a.value, a.attribute_definition_id, 
  (SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk
FROM attribute_values as a
ORDER BY attribute_definition_id

.. no probado.

Otros consejos

SELECT a1.value, a1.attribute_definition_id, a1.value_rk
FROM attribute_values AS a1
  LEFT OUTER JOIN attribute_values AS a2
    ON (a1.value = a2.value AND a1.value_rk < a2.value_rk)
WHERE a2.value IS NULL
ORDER BY a1.attribute_definition_id;

En otras palabras, busque la fila a1 para la cual no existe ninguna fila a2 con el mismo valor y una mayor value_rk .

Esto debería funcionar para PostgreSQL, no sé qué dbms usas.

SELECT DISTINCT ON (value)
  value, 
  attribute_definition_id, 
  value_rk
FROM 
  attribute_values
ORDER BY
  value, 
  attribute_definition_id

Docs de PostgreSQL

¿Es esto lo que estás buscando?

SELECT value, attribute_definition_id, value_rk
FROM attribute_values av1
WHERE value_rk IN (
        SELECT max(value_rk)
        FROM attribute_values av2
        WHERE av2.value = av1.value
)
ORDER BY attribute_definition_id

Si value_rk es único, esto debería funcionar.

Bien, aquí están mis suposiciones:

Servidor SQL estándar

value_rk no es un valor numérico, pero value y attribute_definition_id son numeric.

SELECT value_rk, MIN(value) as value, MIN(attribute_definition_id) as attribute_definition_id
FROM attribute_values
GROUP BY value_rk
ORDER BY MIN(attribute_definition_id)

Si uno de esos campos no es numérico, se requerirá más reflexión, háganoslo saber.

Si está abierto a usar variables de tabla, puede mantenerlo todo dentro de una sola llamada de base de datos como esta:

DECLARE @attribute_values TABLE (value int, attribute_definition_id int, value_rk uniqueidentifier)

INSERT INTO @attribute_values (value)
SELECT DISTINCT value FROM attribute_values

UPDATE @attribute_values
SET attribute_definition_id = av2.attribute_definition_id,
    value_rk = av2.value_rk
FROM @attribute_values av1
INNER JOIN attribute_values av2 ON av1.value = av2.value

SELECT value, attribute_definition_id, value_rk FROM @attribute_values

Esencialmente, está creando un conjunto de registros limitado con la tabla llena de valores únicos de 'valor', y dejando que SQL Server complete los vacíos usando solo una de las coincidencias de la tabla principal.

Editado para agregar: esta sintaxis funciona bien dentro de cfquery.

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
WHERE value, value_rk IN (
        SELECT value, max(value_rk)
        FROM attribute_values
        GROUP BY value
)
ORDER BY attribute_definition_id

NO PROBADO!

No estoy seguro si entiendo completamente su configuración, pero algo como esto funcionaría:

SELECT value, attribute_definition_id, value_rk
FROM attribute_values
GROUP BY value
ORDER BY attribute_definition_id;

Una vez más, no estoy muy seguro de qué columna es la que estás intentando limitar, o cómo quieres limitarla.

Menos elegante de lo que me gustaría: es básicamente lo que estás haciendo, solo en SQL puro, pero funciona y todo puede hacerse en SQL.

DECLARE @mytable TABLE(mykey NVARCHAR(512), myVal NVARCHAR(512))

DECLARE @keyVal NVARCHAR(512)
DECLARE @depVal NVARCHAR(512)
DECLARE myCursor CURSOR for
   SELECT DISTINCT(value) FROM attribute_values
OPEN myCursor
FETCH NEXT FROM myCursor INTO @keyVal
WHILE @@FETCH_STATUS=0
  BEGIN
     SET @depVal = (SELECT TOP 1 attribute_definition_id FROM attribute_values WHERE VALUE=@keyVal ORDER BY attribute_definition_id)
     INSERT INTO @mytable (mykey, myVal) VALUES (@keyVal, @depVal)
     FETCH NEXT FROM myCursor INTO @keyVal
  END
DEALLOCATE myCursor

SELECT * FROM @mytable

Puedes agregar un depVal2 y otros usando este método.

creo

SELECT DISTINCT a.value, a.attribute_definition_id, 
(SELECT TOP 1 value_rk FROM attribute_values WHERE value = a.value) as value_rk
FROM attribute_values as a
ORDER BY attribute_definition_id

trabajado

Como lo señaló John Fiala, la respuesta canónica en el servidor SQL es usar una cláusula grupo por grupo cuando desee realizar una " distinta " Operación sobre un subconjunto de columnas. ¿Por qué es esta la respuesta canónica correcta? Bueno, desea arrastrar columnas que no forman parte de su " distintas " grupo. ¿Exactamente qué filas desea obtener para estas columnas subsidiarias? El uso de una cláusula por grupo y la definición de funciones agregadas para estas columnas subsidiarias hace que su consulta se comporte bien en el sentido de que ahora sabe cómo se obtienen estas columnas subsidiarias. Este artículo da más detalles:

http: // weblogs. sqlteam.com/jeffs/archive/2007/10/12/sql-distinct-group-by.aspx

SELECT value_rk, MIN(value) as value, 
MIN(attribute_definition_id) as attribute_definition_id
FROM attribute_values
GROUP BY value_rk

Además, vale la pena tener en cuenta que MIN y MAX funcionan con texto y varios otros tipos de datos que no son valores numéricos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top