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

Ответы

Ответ 1

Обновлено для использования ваших новых данных:

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

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

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

Ответ 2

Для MySQL:

SELECT contract, activity
FROM table
GROUP BY contract
HAVING COUNT(DISTINCT activity) = 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
)

Ответ 4

Modified!

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

Ответ 5

Попробуйте следующее:

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

Ответ 6

Используя возможность "динамической таблицы" в 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

Ответ 7

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

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

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

Ответ 8

Вот еще один вариант использования 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

Ответ 9

SELECT DISTINCT Contract, Activity
FROM Contract WHERE Contract IN (
SELECT Contract 
FROM Contract
GROUP BY Contract
HAVING COUNT( DISTINCT Activity ) = 1 )

Ответ 10

Извините, вы не используете PostgreSQL...

SELECT DISTINCT ON контракт, активность * Из таблицы ORDER BY contract, activity

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

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

ВЫБЕРИТЕ контракт, активность, счетчик() Из таблицы GROUP BY contract, activity HAVING count() = 1

Ответ 11

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

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

SELECT DISTINCT [column] Как UniqueValues FROM [db]. [Dbo]. [Table]

Ответ 12

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