2008-10-22 11 views
15

Gracias a todos por la respuesta de todos. Lamentablemente, ninguna de las soluciones parece estar funcionando por mi parte, y creo que el ejemplo que he proporcionado está mal.SQL: ¿Cómo selecciono solo las filas con un valor único en cierta columna?

Así que permítanme intentarlo de nuevo.

Mi mesa se parece a esto:

contract project activity 
row1 1000 8000 10 
row2 1000 8000 20 
row3 1000 8001 10 
row4 2000 9000 49 
row5 2000 9001 49 
row6 3000 9000 79 
row7 3000 9000 78 

Básicamente, la consulta Busco volvería "2000,49" por "contrato, la actividad" porque sólo contrato # 2000 tiene uno, y sólo uno , valor de actividad único.

Una vez más, un millón de gracias por adelantado, boroatel

+0

¿Cuál es la PK de esta tabla? –

Respuesta

13

actualizado para utilizar sus datos recientemente proporcionados:

las soluciones utilizando los datos originales se pueden encontrar al final de esta respuesta.

Usando su nuevos datos:

DECLARE @T TABLE([contract] INT, project INT, activity INT) 
INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 

SELECT DISTINCT [contract], activity FROM @T AS A WHERE 
    (SELECT COUNT(DISTINCT activity) 
    FROM @T AS B WHERE B.[contract] = A.[contract]) = 1 

devuelve: 2000, 49

soluciones utilizando los datos originales

ADVERTENCIA: Las siguientes soluciones utilizan los datos previamente dados en la pregunta y puede no tener sentido para la pregunta actual. Los dejé adjuntos solo para completarlos.

SELECT Col1, Count(col1) AS count FROM table 
GROUP BY col1 
HAVING count > 1 

Esto debería obtener una lista de todos los valores en col1 que no son distintos. Puede colocar esto en una mesa var o tabla temporal y unirse contra ella.

Aquí hay un ejemplo usando un sub-consulta:

DECLARE @t TABLE(col1 VARCHAR(1), col2 VARCHAR(1), col3 VARCHAR(1)) 

INSERT INTO @t VALUES('A', 'B', 'C'); 
INSERT INTO @t VALUES('D', 'E', 'F'); 
INSERT INTO @t VALUES('A', 'J', 'K'); 
INSERT INTO @t VALUES('G', 'H', 'H'); 

SELECT * FROM @t 

SELECT col1, col2 FROM @t WHERE col1 NOT IN 
    (SELECT col1 FROM @t AS t GROUP BY col1 HAVING COUNT(col1) > 1) 

Esto devuelve:

D E 
G H 

Y otro método que los usuarios de una tabla temporal y se unen:

DECLARE @t TABLE(col1 VARCHAR(1), col2 VARCHAR(1), col3 VARCHAR(1)) 

INSERT INTO @t VALUES('A', 'B', 'C'); 
INSERT INTO @t VALUES('D', 'E', 'F'); 
INSERT INTO @t VALUES('A', 'J', 'K'); 
INSERT INTO @t VALUES('G', 'H', 'H'); 

SELECT * FROM @t 

DROP TABLE #temp_table 
SELECT col1 INTO #temp_table 
    FROM @t AS t GROUP BY col1 HAVING COUNT(col1) = 1 

SELECT t.col1, t.col2 FROM @t AS t 
    INNER JOIN #temp_table AS tt ON t.col1 = tt.col1 

también devoluciones:

D E 
G H 
+0

No estoy seguro de cómo era la pregunta original cuando respondió esto, pero dado lo que hay ahora, falla el objetivo y es extremadamente difícil mapear al objetivo.Sospecho que es porque tenía menos información para trabajar que ahora. –

+1

Sí, el asker cambió la pregunta y utilizó un conjunto de datos diferente. Las respuestas dadas anteriormente se completaron con el conjunto de datos proporcionado. Actualicé la respuesta para reflejar esto y agregué una solución usando el nuevo conjunto de datos. – vfilby

7

Para MySQL:

SELECT contract, activity 
FROM table 
GROUP BY contract 
HAVING COUNT(DISTINCT activity) = 1 
+0

Esto tampoco funciona, no puede tener columnas en la lista de selección que no están en GROUP BY ni en un agregado. Tendrá que usar el mismo principio pero en una consulta secundaria o unirse. – vfilby

+0

en realidad probé mi código en MySQL y funciona – mrm

+0

* funcionó (con el primer ejemplo de datos) – mrm

2

Modificado!

SELECT distinct contract, activity from @t a 
WHERE (SELECT COUNT(DISTINCT activity) FROM @t b WHERE b.contract = a.contract) = 1 

Y aquí hay otro - más corto/más limpio y sin subconsulta

select contract, max(activity) from @t 
group by contract 
having count(distinct activity) = 1 
+0

Cuando se prueba en IBM Informix Dynamic Server 11.50, no genera datos. El problema es que el contrato 2000 tiene dos filas de proyecto con el mismo código de actividad, por lo que el COUNT (*) devuelve 2, no 1. –

+0

@Jonathan: la pregunta es sobre Microsoft SQL Server, por lo que la implementación de SQL de Informix es completamente irrelevante aquí. –

+0

Es cierto que IDS no es directamente relevante, pero es una implementación de SQL válida y el SQL anterior se ejecuta, pero no produce la respuesta correcta. –

2

Prueba esto:

select 
     contract, 
     max (activity) 
from 
     mytable 
group by 
     contract 
having 
     count (activity) = 1 
+0

Cuando se prueba en IBM Informix Dynamic Server 11.50, esto no produce datos, no la fila con 2000,49 según sea necesario. El problema es que el contrato 2000 tiene dos filas de proyecto con el mismo código de actividad, por lo que el recuento (actividad) = 2 y no 1 como se requiere. –

+0

Esto no funciona en SQL Server 2005. El problema aquí es que hay dos filas para 2000,49. Necesita contar solo actividades distintas. – vfilby

+0

A la luz de estos comentarios, ver la respuesta de Jetson. –

1

Asumiendo que su tabla de datos se llama ProjectInfo:

SELECT DISTINCT Contract, Activity 
    FROM ProjectInfo 
    WHERE Contract = (SELECT Contract 
          FROM (SELECT DISTINCT Contract, Activity 
            FROM ProjectInfo) AS ContractActivities 
          GROUP BY Contract 
          HAVING COUNT(*) = 1); 

La consulta más interna identifica th e los contratos y las actividades. El siguiente nivel de la consulta (el medio) identifica los contratos en los que solo hay una actividad. La consulta externa extrae el contrato y la actividad de la tabla ProjectInfo para los contratos que tienen una sola actividad.

Probado con IBM Informix Dynamic Server 11.50: debería funcionar también en otros lugares.

1

Aquí es otra opción utilizando servidores SQL recuento diferente:

DECLARE @T TABLE([contract] INT, project INT, activity INT) 
INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 



SELECT DISTINCT [contract], activity FROM @T AS A WHERE 
    (SELECT COUNT(DISTINCT activity) 
    FROM @T AS B WHERE B.[contract] = A.[contract]) = 1 
1
SELECT DISTINCT Contract, Activity 
FROM Contract WHERE Contract IN (
SELECT Contract 
FROM Contract 
GROUP BY Contract 
HAVING COUNT(DISTINCT Activity) = 1) 
+0

Probado con MS SQL 2005 – Hapkido

2

La utilización de la capacidad "tabla dinámica" en SQL Server (consulta contra una consulta paréntesis rodeado), puede devolver 2000, 49 w/lo siguiente. Si su plataforma no ofrece un equivalente a la extensión ANSI de "tabla dinámica", siempre puede utilizar una tabla temporal en instrucción de dos pasos insertando los resultados dentro de la "tabla dinámica" en una tabla temporal, y luego realizar una selección posterior en la tabla temporal.

DECLARE @T TABLE(
    [contract] INT, 
    project INT, 
    activity INT 
) 

INSERT INTO @T VALUES(1000, 8000, 10) 
INSERT INTO @T VALUES(1000, 8000, 20) 
INSERT INTO @T VALUES(1000, 8001, 10) 
INSERT INTO @T VALUES(2000, 9000, 49) 
INSERT INTO @T VALUES(2000, 9001, 49) 
INSERT INTO @T VALUES(3000, 9000, 79) 
INSERT INTO @T VALUES(3000, 9000, 78) 

SELECT 
    [contract], 
    [Activity] = max (activity) 
FROM 
    (
    SELECT 
     [contract], 
     [Activity] 
    FROM 
     @T 
    GROUP BY 
     [contract], 
     [Activity] 
    ) t 
GROUP BY 
    [contract] 
HAVING count (*) = 1 
1

En este momento no se está usando PostgreSQL ...

SELECT DISTINCT en el contrato, la actividad * DE thetable ORDER BY contrato, la actividad

http://www.postgresql.org/docs/8.3/static/sql-select.html#SQL-DISTINCT

Oh, espera. Desea que los valores con exactamente un ...

contrato SELECT, la actividad, el recuento () DE GRUPO POR thetable contrato, actividad que tenga recuento () = 1

3

Soy un fan de NO EXISTE

SELECT DISTINCT contract, activity FROM table t1 
WHERE NOT EXISTS (
    SELECT * FROM table t2 
    WHERE t2.contract = t1.contract AND t2.activity != t1.activity 
) 
0

lo sentimos antiguo puesto sé, pero tuve el mismo problema, no podía conseguir cualquiera de los anteriores a trabajar para mí, sin embargo lo he descubierto.

Esto funcionó para mí:..

SELECT DISTINCT [columna] Como UniqueValues ​​ DE [db] [dbo] [Tabla]

0

SELECT DISTINCT Col1, Col2 DE Tabla GROUP BY Col1 CUENTA QUE TIENE (DISTINCT Col1) = 1

Cuestiones relacionadas