SQL:如何查询所有列的不同值

时间:2014-01-22 20:03:07

标签: sql ms-access

例如, 该表有3行3列:

姓名年龄性别
彼得25米
约翰29米
Alex 25 M

我想查询表格并获取

姓名年龄性别
彼得25米
约翰29
亚历克斯

我尝试的方法:

SELECT DISTINCT Name,Age,Gender FROM table

输出仍然是

姓名年龄性别
彼得25米
约翰29米
Alex 25 M

如何实现每个字段没有冗余条目的表?感谢。

感谢大家的帮助,特别是donPablo的帮助。 这是我的VBA代码来实现这一目标。由于我对VBA完全不熟悉,因此代码可能不是非常干净和高效。但至少它有效。

Option Compare Database

Sub ReadDistinctValue()

Dim d As Database
Dim rs As Recordset
Dim FN As Field, Age As Field, Sex As Field

Set d = CurrentDb()
Set rs = d.OpenRecordset("Table1")
Set FN = rs.Fields("FN")
Set Age = rs.Fields("Age")
Set Sex = rs.Fields("Sex")

d.Execute "CREATE TABLE Table4 (FN Text,Age Text,Sex Text)"

While Not rs.EOF
    If CheckFN(FN) = False Then
        Call WriteFN(FN)
    End If
    If CheckAge(Age) = False Then
        Call WriteAge(Age)
    End If
    If CheckSex(Sex) = False Then
        Call WriteSex(Sex)
    End If
    rs.MoveNext
Wend

rs.Close

End Sub

Function CheckFN(FN As Field) As Boolean

Dim d As Database
Dim rs_new As Recordset
Dim FN_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set FN_new = rs_new.Fields("FN")

CheckFN = False

Do While Not rs_new.EOF
    If FN_new = FN Then
        CheckFN = True
        Exit Do
    End If
    rs_new.MoveNext
Loop

rs_new.Close

End Function

Function WriteFN(FN As Field)
Dim d As Database
Dim rs_new As Recordset
Dim FN_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set FN_new = rs_new.Fields("FN")

If Not rs_new.EOF Then
    rs_new.MoveFirst
End If

Do While True
    If rs_new.EOF Then
        rs_new.AddNew
        FN_new = FN
        rs_new.Update
        Exit Do
    End If
    If IsNull(FN_new.Value) Then
        rs_new.Edit
        FN_new = FN
        rs_new.Update
        Exit Do
    End If
    rs_new.MoveNext
Loop
rs_new.Close
End Function

Function CheckAge(Age As Field) As Boolean

Dim d As Database
Dim rs_new As Recordset
Dim Age_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set Age_new = rs_new.Fields("Age")

CheckAge = False

Do While Not rs_new.EOF
    If Age_new = Age Then
        CheckAge = True
        Exit Do
    End If
    rs_new.MoveNext
Loop

rs_new.Close

End Function

Function WriteAge(Age As Field)
Dim d As Database
Dim rs_new As Recordset
Dim Age_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set Age_new = rs_new.Fields("Age")

If Not rs_new.EOF Then
    rs_new.MoveFirst
End If

Do While True
    If rs_new.EOF Then
        rs_new.AddNew
        Age_new = Age
        rs_new.Update
        Exit Do
    End If
    If IsNull(Age_new.Value) Then
        rs_new.Edit
        Age_new = Age
        rs_new.Update
        Exit Do
    End If
    rs_new.MoveNext
Loop
rs_new.Close
End Function

Function CheckSex(Sex As Field) As Boolean

Dim d As Database
Dim rs_new As Recordset
Dim Sex_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set Sex_new = rs_new.Fields("Sex")

CheckSex = False

Do While Not rs_new.EOF
    If Sex_new = Sex Then
        CheckSex = True
        Exit Do
    End If
    rs_new.MoveNext
Loop

rs_new.Close

End Function

Function WriteSex(Sex As Field)
Dim d As Database
Dim rs_new As Recordset
Dim Sex_new As Field

Set d = CurrentDb()
Set rs_new = d.OpenRecordset("Table4")
Set Sex_new = rs_new.Fields("Sex")

If Not rs_new.EOF Then
    rs_new.MoveFirst
End If

Do While True
    If rs_new.EOF Then
        rs_new.AddNew
        Sex_new = Sex
        rs_new.Update
        Exit Do
    End If
    If IsNull(Sex_new.Value) Then
        rs_new.Edit
        Sex_new = Sex
        rs_new.Update
        Exit Do
    End If
    rs_new.MoveNext
Loop
rs_new.Close
End Function

3 个答案:

答案 0 :(得分:0)

通过命名三列,您将检索该组值的不同组合。

如果您需要不同值的列表,请在选择中单独命名。

SELECT DISTINCT Name FROM table

SELECT DISTINCT Age FROM table

SELECT DISTINCT Gender FROM table

如果您尝试按照示例中的方式显示它们,则必须通过某些GUI功能来完成。 SQL数据库引擎不擅长显示技巧,只是处理数据。

答案 1 :(得分:0)

我已经稍微扩展了表值,只是为了看看会发生什么 -

FN      Age Sex
Alice   28  F
Ben     19  M
Charles 33  M
Doug    23  M
Elaine  21  F
Frank   25  M
Gwen    28  F
Helen   33  F
Alice   17  F
Ben     21  F

然后我为FN开发了一个查询,后来推广到所有三个字段 -

线索是对每个FN / AGE / SEX进行排序,然后加入该seq# -

SELECT 
   AB.fn,
   CD.age,
   EF.sex

FROM   
((SELECT A.fn, Count(B.fn) AS CNTfn
    FROM   
    (SELECT DISTINCT fn FROM   table1) AS A,
    (SELECT DISTINCT fn FROM   table1) AS B
    WHERE  B.fn <= A.fn
    GROUP  BY A.fn) AS AB

LEFT JOIN 
 (SELECT C.age, Count(D.age) AS CNTage
    FROM   
    (SELECT DISTINCT age FROM   table1) AS C,
    (SELECT DISTINCT age FROM   table1) AS D
    WHERE  D.age <= C.age
    GROUP  BY C.age) AS CD
ON AB.cntfn = CD.cntage)

LEFT JOIN 
 (SELECT E.sex, Count(F.sex) AS CNTsex
    FROM   
    (SELECT DISTINCT sex FROM   table1) AS E,
    (SELECT DISTINCT sex FROM   table1) AS F
    WHERE  F.sex <= E.sex
    GROUP  BY E.sex) AS EF
ON AB.cntfn = EF.CNTsex;

这给出了所需的结果 -

FN  AGE SEX
Alice   17  F
Ben     19  M
Charles 21  
Doug    23  
Elaine  25  
Frank   28  
Gwen    33  
Helen       

我在示例表中更改了Sex,并将以下内容添加到un-Distinct整个表的第一个序列中,并将ON ...更改为XZ.cntall ...

(SELECT X.FN & X.AGE & X.SEX, Count(*) AS CNTall
FROM   
(SELECT DISTINCT FN, AGE,  SEX FROM   table1) AS X,
(SELECT DISTINCT FN, AGE,  SEX FROM   table1) AS Z
WHERE  Z.FN & Z.AGE & Z.SEX <= X.FN & X.AGE & X.SEX
GROUP  BY X.FN,  X.AGE,  X.SEX) as XZ

现在获得这些结果

fn     age  sex
Alice   17  M
Ben     19  N
Charles 21  O
Doug    23  P
Elaine  25  Q
Frank   28  R
Gwen    33  W
Helen       X
            Y
            Z

答案 2 :(得分:-2)

可能有一个SQL解决方案。我不断惊讶于可以做些什么。但是,我的答案是,这是VBA的完美应用。