Спасибо всем за отклик. К сожалению, ни одно из решений, похоже, не работает с моей стороны, и я предполагаю, что приведенный мной пример испорчен.
Так что позвольте мне попробовать еще раз.
Моя таблица выглядит так:
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 имеет одно и ТОЛЬКО одно уникальное значение действия.
Опять же, заранее миллион спасибо, бороатель





Обновлено для использования ваших вновь предоставленных данных:
Решения с использованием исходных данных можно найти в конце этого ответа.
Используя ваши новые данные:
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 table и присоединиться к ней.
Вот пример использования подзапроса:
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
Я не уверен, как выглядел исходный вопрос, когда вы ответили на него, но, учитывая то, что есть сейчас, он не попадает в цель, и его чрезвычайно трудно сопоставить с целью. Я подозреваю, что это потому, что тогда у вас было меньше информации для работы, чем у нас сейчас.
Да, спрашивающий изменил вопрос и использовал другой набор данных. Приведенные выше ответы были полными с предоставленным набором данных. Я обновил ответ, чтобы отразить это, и добавил решение с использованием нового набора данных.
Для MySQL:
SELECT contract, activity
FROM table
GROUP BY contract
HAVING COUNT(DISTINCT activity) = 1
Это также не работает, у вас не может быть столбцов в списке выбора, которые не входят в GROUP BY или агрегат. Вам придется использовать тот же принцип, но во вспомогательном запросе или присоединении.
Мое плохое, это ограничение SQL Server. Я не понимал, что MySQL может иметь элементы в списке выбора, которые не были агрегатной функцией или в группе по. Извини друг.
Изменено!
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
При тестировании в IBM Informix Dynamic Server 11.50 он не выдает данных. Проблема в том, что в контракте 2000 есть две строки проекта с одинаковым кодом активности, поэтому COUNT (*) возвращает 2, а не 1.
@Jonathan: вопрос касается Microsoft SQL Server, поэтому реализация SQL в Informix здесь совершенно неуместна.
Верно, что IDS не имеет прямого отношения, но это допустимая реализация SQL, и приведенный выше SQL выполняется, но не дает правильного ответа.
Попробуй это:
select
contract,
max (activity)
from
mytable
group by
contract
having
count (activity) = 1
При тестировании в IBM Informix Dynamic Server 11.50 это не дает ни данных, ни строки с 2000,49, как требуется. Проблема в том, что в контракте 2000 есть две строки проекта с одинаковым кодом активности, поэтому count (activity) = 2, а не 1, как требуется.
Это не работает в SQL Server 2005. Проблема в том, что для 2000,49 есть две строки. Вам нужно считать только отдельные виды деятельности.
В свете этих комментариев см. Ответ Джетсона.
Предполагая, что ваша таблица данных называется 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 - должно работать и в другом месте.
Вот еще один вариант использования подсчета серверов 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
SELECT DISTINCT Contract, Activity
FROM Contract WHERE Contract IN (
SELECT Contract
FROM Contract
GROUP BY Contract
HAVING COUNT( DISTINCT Activity ) = 1 )
Используя возможность "динамической таблицы" в SQL Server (запрос по запросу, заключенному в круглые скобки), вы можете вернуть 2000, 49 со следующим. Если ваша платформа не предлагает эквивалента ANSI-расширения «динамической таблицы», вы всегда можете использовать временную таблицу в двухэтапном / операторе, вставив результаты из «динамической таблицы» во временную таблицу, а затем выполнив последующий выбор в таблице темп.
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
Извините, вы не используете PostgreSQL ...
ВЫБЕРИТЕ РАЗЛИЧИЕ ПО контракту, деятельности * Со стола ЗАКАЗАТЬ договор, деятельность
http://www.postgresql.org/docs/8.3/static/sql-select.html#SQL-DISTINCT
Ой, погоди. Вам нужны только значения с одним ...
ВЫБЕРИТЕ контракт, активность, количество () ИЗ таблицы GROUP BY контракта, активность HAVING count () = 1
Я фанат НЕ СУЩЕСТВУЕТ
SELECT DISTINCT contract, activity FROM table t1
WHERE NOT EXISTS (
SELECT * FROM table t2
WHERE t2.contract = t1.contract AND t2.activity != t1.activity
)
Извините, старый пост, который я знаю, но у меня была такая же проблема, я не мог заставить что-либо из вышеперечисленного работать для меня, однако я понял это.
Это сработало для меня:
ВЫБЕРИТЕ DISTINCT [столбец] как уникальные значения ОТ [db]. [Dbo]. [Table]
ВЫБРАТЬ DISTINCT Col1, Col2 ИЗ ГРУППЫ таблиц ПО Col1, ИМЕЮЩИЕ СЧЕТ (DISTINCT Col1) = 1
Что такое ПК для этой таблицы?