2008-10-22 7 views
15

Спасибо миллиону всех за ответ каждого. К сожалению, ни одно из решений, похоже, не работает с моей стороны, и я предполагаю, что приведенный мной пример испорчен.SQL: Как я могу выбрать только строки с уникальным значением в определенном столбце?

Так что позвольте мне попробовать еще раз.

Моя таблица выглядит следующим образом:

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 

В принципе, запрос я искал бы вернуть «2000,49» для «договора, деятельность», потому что только контракт # 2000 имеет один и только один , уникальное значение активности.

Опять же, спасибо миллион заранее, boroatel

+0

Что такое ПК для этой таблицы? – 2011-06-14 13:43:00

ответ

13

Обновлено использовать недавно представленную данные:

Растворы, используя исходные данные могут быть найдены в конце этого ответа.

Использование новых данных:

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 

возвращается: 2000, 49

Решения с использованием исходных данных

ВНИМАНИЕ: Следующие решения используют данные ранее приведенные в вопрос и может не иметь смысла для текущего вопроса. Я оставил их прикрепленными только для полноты.

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

Это должно предоставить вам список всех значений в col1, которые не отличаются друг от друга. Вы можете поместить это в таблицу таблицы var или temp и присоединиться к ней.

Вот пример, используя подзапрос:

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) 

Это возвращает:

D E 
G H 

И еще один метод, который пользователи таблицы температуры и присоединиться:

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 

Рекомендуем также возвращается:

D E 
G H 
+0

Я не уверен, как выглядел исходный вопрос, когда вы ответили на это, но учитывая то, что сейчас есть, оно пропускает цель и крайне сложно сопоставить цель.Я подозреваю, что это потому, что у вас было меньше информации для работы с нами, чем сейчас. – 2008-10-22 03:15:28

+1

Да, вопросник изменил вопрос и использовал другой набор данных. Ответы, приведенные выше, были дополнены данным набора данных. Я обновил ответ, чтобы отразить это, и добавил решение, используя новый набор данных. – vfilby 2008-10-22 03:39:55

7

Для MySQL:

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

Это также не работает, вы не можете иметь столбцы в списке выбора, которые не находятся в GROUP BY или агрегате. Вам придется использовать тот же принцип, но в подзапросе или подключиться. – vfilby 2008-10-22 02:26:17

+0

На самом деле я протестировал свой код в MySQL, и он работает – mrm 2008-10-22 03:34:25

+0

* работал (с данными первого примера) – mrm 2008-10-22 03:42:46

2

Модифицированный!

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

А вот еще один - короче/очиститель без подзапроса

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

Попробуйте это:

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

Предполагая, что ваша таблица данных называется 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); 

Самый внутренний запрос идентифицирует th e контрактов и мероприятий. Следующий уровень запроса (средний) определяет контракты, в которых есть только одно действие. Затем внешний запрос вытягивает контракт и активность из таблицы ProjectInfo для контрактов, которые имеют одно действие.

Протестировано с использованием IBM Informix Dynamic Server 11.50 - должно работать и в других местах.

1

Вот еще один вариант с использованием SQL-сервера подсчитывать отчетливыми:

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) 
2

Используя "динамическую таблицу" возможности в SQL Server (запрос от запроса скобки окруженного), вы можете вернуть 2000, 49 с последующим. Если ваша платформа не предлагает эквивалент ANSI-расширения с динамической таблицей, вы всегда можете использовать временную таблицу в двухэтапном/выводе, вставив результаты в «динамическую таблицу» в временную таблицу, а затем выполняя последующий выбор в таблице temp.

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

К сожалению, вы не используете PostgreSQL ...

SELECT DISTINCT по контракту, деятельность * ОТ ORDER таблицы, с по контракту, деятельность

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

Ой, подождите. Вы хотите только значения с точно один ...

ВЫБРАТЬ контракт, активность, количество () ОТ GROUP BY таблицы, с контрактом, деятельность ИМЕТЬ отсчет () = 1

3

Я поклонник NOT EXISTS

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

к сожалению старый пост я знаю, но у меня была такая же проблема, не мог получить любой из вышеперечисленных работать для меня, но я понял это.

Это работало для меня:..

SELECT DISTINCT [столбец] Как UniqueValues ​​ ОТ [дБ] [DBO] [таблица]

0

SELECT DISTINCT Col1, Col2 из Таблицы GROUP BY COL1 HAVING COUNT (DISTINCT Col1) = 1

Смежные вопросы