select独一无二,和一个双打
我有一个列A,B和C列表。列A可能有重复。
我需要一个查询,将得到我在A列中的唯一值的结果集,我不在乎可能重复它需要。
对于其余的数据,我什么都不知道。
一个例子可能是:
ABC 1 8 8 1 7 7 2 10 10
在这种情况下,我想select:
ABC 1 xx 2 10 10
x =它将select哪个值并不重要。
亲切的问候,
马提亚斯万斯
编辑
我以为我发现我的解决scheme:
SELECT * FROM ( SELECT * FROM test GROUP BY a ) table_test;
但毕竟这不是工作。
这将导致:
[Microsoft][ODBC Excel Driver] Cannot group on fields selected with '*'
尝试这个:
select A, B, C from test x where not exists (select * from test y where yA = xA and (yB < xB or (yB = xB and yC < xC)) order by A
但是因为它包含相关的子查询,所以可能会很慢。 (OTOH至less理论上可以使数据库引擎将其优化为我在下面展示的东西。)
那么SQL之外的东西呢? 你打算怎么做的结果?
如果你打算用一些程序来处理它,为什么不只是得到:
select A, B, C from test order by A, B, C
然后做一些事情:
prev_a = None for a, b, c in get_query_result(): if a != prev_a: prev_a = a yield (a, b, c)
在你的应用程序?
我不知道PHP,但我想这将是这样的:
$query = "SELECT a,b,c FROM test ORDER BY a,b,c"; $result = odbc_exec($connect, $query); $prev_a = NULL; # I don't know what you would normally use here in PHP while (odbc_fetch_row($result)) { $a = odbc_result($result, 1); if (is_null($prev_a) or $a != $prev_a) { $b = odbc_result($result, 2); $c = odbc_result($result, 3); print("A = $a, B = $b, C = $c\n"); $prev_a = $a; } }
这个简单的查询不会工作:
SELECT A, MIN(B), MIN(C) FROM test GROUP BY A
它按A进行分组,只是在A行中selectB和C的最小值.B和C的值可能来自不同的行,例如
ABC 1 2 3 1 4 1
会返回
ABC 1 2 1
困难的部分是从同一行获得b
和c
。 以下查询使用子查询来消除b
或c
没有最低值的行。 它自己join表格,并且说不能有更低的b
或c
值的行。 “不”是由WHERE子句中的prev.a is null
实现的。
子查询被称为semiunique
因为仍然可能有相同的b
和c
重复行。 外部查询照顾那些与GROUP BY。 由于b
和c
是相同的,因此我们select哪一行并不重要,所以我们可以使用min()
来select一个。
select a, min(b), min(c) from ( select cur.a, cur.b, cur.c from YourTable cur left outer join YourTable prev on cur.a = prev.a and (cur.b > prev.b or (cur.b = prev.b and cur.c > prev.c)) where prev.a is null ) semiunique group by semiunique.a
根据你的评论,一个更简单的版本来抓住“东西”为b
和c
:
select a, min(b), min(c) from YourTable group by a
这在SQL Server 2008中有效,它说明了这个概念。 你需要一个独特的专栏。
declare @temp as table ( id int identity(1,1), a int, b int, c int) insert into @temp select 1 as A, 8 as B, 8 as C union select 1, 7, 7 union select 2, 10, 10 select a, b, c from @temp where id in (select MAX(id) from @temp group by a)
看到你正在使用Excel,我会使用相同的原则。 将另一列添加到电子表格并确保它是唯一的。 使用该列作为您的ID列。
Select A , Max(b) //Since You don't care about the Value , Max(c) //Since You don't care about the Value From table t Group By A
-- All rows that are unique in column A select * from table where col_a in (select col_a from table group by col_a having count(*)=1) -- One row per dupe select * from table where col_a in (select max(col_a) from table group by col_a having count(*)>1)
A中具有唯一值的所有行
SELECT * FROM table t1 INNER JOIN (SELECT A FROM table GROUP BY A HAVING COUNT(A) = 1) as t2 ON t1.A = t2.A
我不明白“A中具有重复值之一的行之一”是什么意思。 你能解释一下好吗?
用你的例子,在MySQL中只是做
SELECT * FROM table GROUP BY A
会给你想要的结果:
ABC 1 8 8 2 10 10
另一种select是使用ROW_NUMBER()函数。 不知道它是否在ODBC Excel驱动程序中有效:
select a, b, c from ( select * , ROW_NUMBER() OVER (PARTITION BY A ORDER BY A) as RN from @temp ) q where rn = 1
我知道这是一个肮脏的方式,但将工作这种情况。
伪代码:
创build表#tmpStaging主键为col(A)
对于flatFile / excel /中的每一行开始尝试插入#tmpstaging结束尝试
开始捕捉 – 没有结束
从#tmpstagingselect*会给你没有dups的行
这会给你每一个副本的第一个
SELECT DISTINCT A, (SELECT TOP 1 B FROM @Table tB WHERE tb.A = tA) B, (SELECT TOP 1 C FROM @Table tB WHERE tb.A = tA) C FROM @Table t
尝试这个,
SELECT UT.[A], (SELECT TOP 1 B FROM [YourTable] WHERE [YourTable].A= UT.A) AS B, (SELECT TOP 1 C FROM [YourTable] WHERE [YourTable].A= UT.A) AS C FROM [YourTable] AS UT GROUP BY UT.[A]
我还没有尝试过…谁知道:)
select * from table T where id = ( select min(id) from table where a = Ta )
UPD。 但是如果表中没有主键(为什么?),那么:
select A, min(B), min(C) from TABLE group by A