SQL:如何仅选择某列上具有唯一值的行?

时间:2008-10-22 01:55:07

标签: sql-server

感谢每个人对每个人的回应。不幸的是,没有一个解决方案似乎在我的最终工作,我的猜测是我提供的例子搞砸了。

所以让我再试一次。

我的表格如下:

    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

12 个答案:

答案 0 :(得分: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

答案 1 :(得分:7)

对于MySQL:

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

答案 2 :(得分: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
)

答案 3 :(得分: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

答案 4 :(得分:2)

试试这个:

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

答案 5 :(得分:2)

利用SQL Server中的“动态表”功能(查询括号括起的查询),您可以返回2000,49 w /以下内容。 如果您的平台不提供与“动态表”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

答案 6 :(得分: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);

最里面的查询标识合同和活动。查询的下一级(中间一级)标识只有一个活动的合同。然后,最外层的查询从ProjectInfo表中提取具有单个活动的合同的合同和活动。

使用IBM Informix Dynamic Server 11.50进行测试 - 也应该在其他地方工作。

答案 7 :(得分:1)

这是使用sql servers count distinct的另一个选项:

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

答案 8 :(得分:1)

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

答案 9 :(得分:1)

抱歉,您没有使用PostgreSQL ...

SELECT DISTINCT ON合约,活动 * 来自thetable ORDER BY合同,活动

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

等等哦。您只需要具有一个...

的值

SELECT合约,活动,计数() 从thetable GROUP BY合约,活动HAVING count()= 1

答案 10 :(得分:0)

对不起老帖子我知道,但我有同样的问题,无法让上述任何一个为我工作,但我想出来了。

这对我有用:

SELECT DISTINCT [column] As UniqueValues   FROM [db]。[dbo]。[table]

答案 11 :(得分:0)

SELECT DISTINCT Col1,Col2 FROM Table GROUP BY Col1 HAVING COUNT(DISTINCT Col1)= 1