2012-07-20 17 views
5

He la siguiente tabla en SQL Server 2008:SELECT DISTINCT con LEFT JOIN, ordenados por en t-SQL

CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT) 

INSERT tbl VALUES 
(1, '05:00', '6:00', 1), 
(2, '05:00', '7:00', 1), 
(3, '05:01', '8:00', 1), 
(4, '05:00', '8:00', 1), 
(5, '05:00', '6:00', 2), 
(6, '05:00', '7:00', 2) 

que selecciona ID de todos los registros del mismo tipo, con la misma fecha dtIn, ordenada por Stout en orden ascendente:

SELECT DISTINCT tbl.id FROM tbl 
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

Pero me da un error:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified

he intentado poner que ORDER BY en d diferentes lugares y todo parece no funcionar. ¿Qué estoy haciendo mal aquí?

+5

Como el mensaje de error dice claramente: si está utilizando 'SELECT DISTINCT', las columnas especificadas en la cláusula' ORDER BY' también deben aparecer en la lista de columnas seleccionadas, por lo tanto, use 'SELECT DISTINCT tbl.id , tbl.dtOut FROM ..... ' –

+0

Oh. Ya veo. Entonces tengo que seleccionarlos también. Hmm ... requisito interesante ... pero, bueno ... – ahmd0

Respuesta

3

Al limitar la búsqueda de id individuales, se crea la posibilidad de que cada ID puede tener más de un dtOut asociada a ella. Cuando eso sucede, ¿cómo sabrá Sql Server qué orden usar?

usted podría intentar:

SELECT t1.id 
FROM tbl t1 
LEFT JOIN tbl t2 on t1.type = t2.type AND t1.dtIn = t2.dtIn 
GROUP BY t1.id, t2.dtOut 
ORDER BY t2.dtOut 

Sin embargo, como he mencionado anteriormente que esto puede abrir la posibilidad de tener el mismo id aparece más de una vez, si coincide con más de registro en la tabla del lado derecho.

+0

No lo hace Parece que su declaración funciona: Nombre de la columna ambigua 'dtOut'. – ahmd0

+0

Solucionado. Olvídese del alias de la tabla en la orden por cláusula –

+0

También: una vez más, el problema aquí es que realmente lo que está pidiendo no tiene ningún significado. está diciendo "agrupe esta cesta de frutas por tipo (manzanas, naranjas, etc.), acórtela a solo una de cada tipo, y luego clasifique por tiempo cada fruta que se recogió." En el contexto de una base de datos, si hay Hay muchas manzanas en la cesta que fueron recogidas en diferentes momentos, realmente no sabe qué valor usar. –

0

Puede usar solo aquellas columnas en la cláusula ORDER BY que son parte de su declaración de selección cuando usa la palabra clave 'DISTINCT'. Por lo tanto, puede realizar el pedido solo por tbl.id

Si los ids son únicos, la palabra clave DISTINCT no tiene ningún sentido y causará degradación del rendimiento y puede simplemente eliminarla. En caso de que no lo estén y usted decida seleccionar también tbl.dtOut mientras mantiene DISTINCT, el par tbl.id y tbl.dtOut pueden darle múltiples entradas que tengan el mismo tbl.id que probablemente no sea deseado.

Compruebe this article para posibles soluciones y explicaciones de por qué tales consultas están prohibidas.

0

Debe incluir la columna tbl.dtOut en su lista de selección para que sepa en qué orden.

SELECT DISTINCT tbl.id, tbl.dtOut FROM tbl 
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 
+0

funciona de la forma en que lo pones. Gracias. – ahmd0

6

No tiene sentido ORDENAR por una columna que no está incluida en la lista de elementos DISTINCT.

Usemos un escenario simple. En primer lugar, una mesa FruitPerson:

Fruit PersonName 
----- ------ 
Apple Joe 
Apple Mary 
Peach Karen 
Peach Lance 

Aquí está la consulta equivalente a lo que estamos tratando de hacer:

SELECT DISTINCT Fruit 
FROM FruitPerson 
ORDER BY PersonName; 

El resultado de esta consulta sin la ORDER BY es la siguiente:

Fruit 
----- 
Apple 
Peach 

Pero ahora, la pregunta es: ¿cómo debería el motor ordenar estos dos valores "Apple" y "Peach" por PersonName? ¿Cuál PersonNames? ¡Hay dos personas por fruto! ¿Qué nombre (s), exactamente, debería usar para decidir si Apple o Peach son lo primero?

su lugar, vuelva a escribir la consulta como un agregado:

SELECT Fruit, MinName = Min(PersonName) -- which name to order on 
FROM FruitPerson 
GROUP BY Fruit -- here's how you get your distinctness 
ORDER BY MinName; 
+0

Gracias por explicar esto. Tiene sentido de la forma en que lo pones ... Debo admitir que SQL no es mi fuerte :) y ahora estoy atascado con otro problema :( – ahmd0

+0

Esta es una gran explicación, gracias por la ayuda. –

0

Tenía este error porque no puso (tbl.dtOut) en la lista de selección.

SELECT DISTINCT tbl.dtOut FROM tbl  
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

le conseguirá una conjunto de resultados (que tiene 3 filas) y si desea que el campo id demasiado continuación

SELECT DISTINCT tbl.dtOut, tbl.ID FROM tbl  
    LEFT JOIN tbl AS t1 
    ON tbl.type = t1.type AND 
    tbl.dtIn = t1.dtIn 
    ORDER BY tbl.dtOut ASC 

(que tiene 6 filas, ya que da la combinación distinta de Identificación/fecha campo)