SQL - 使用字段转置选择DISTINCT

时间:2011-10-25 09:59:38

标签: sql ms-access concatenation distinct transpose

我有一张这样的表:

    cod_amb | field_a | field_b | field_c | field_d | field_e

    21      | N.A.    | Fixed   | N.A.    | N.A.    | Natural   
    21      | Conif   | Temp    | N.A.    | >5 years| Artificial
    21      | N.A.    | Fixed   | N.A.    | N.A.    | Natural   
    24      | N.A.    | Fixed   | N.A.    | N.A.    | Natural   
    24      | NR      | Fixed   | N.A.    | <5 years| Natural   
    24      | N.A.    | Temp    | N.A.    | N.A.    | Natural   
    21      | N.A.    | Fixed   | N.A.    | N.A.    | Natural   

我必须得到这样的结果表:

    cod_amb | param   | value               |

    21      | field_a | N.A., Conif         |
    21      | field_b | Fixed, Temp         |
    21      | field_c | N.A.                |
    21      | field_d | N.A., >5 years      |
    21      | field_e | Natural, Artificial |  
    24      | field_a | N.A., NR            |
    24      | field_b | Fixed, Temp         |
    24      | field_c | N.A.                |
    24      | field_d | N.A., <5 years      |
    24      | field_e | Natural             |

拜托,有人可以帮帮我吗?提前谢谢。
SQL for Access 2007

@@@@@@@@@@@@@@@@@@@@@@
更新

我在Access中编写了这个例程:

Sub printSQL()
Dim db As Database
Set db = CurrentDb()
Dim tab As String
tab = "tab_011"
Dim rs1 As dao.Recordset
Set rs1 = db.OpenRecordset(tab)
Dim sqlAll As String
Dim str() As String
Dim i As Integer
i = 0
ReDim str(i)
Dim fld As dao.Field
For Each fld In rs1.Fields
    If fld.Name = "Area" Then
    ElseIf fld.Name = "lungh" Then
    ElseIf fld.Name = "id_elem" Then
    ElseIf fld.Name = "id_tass" Then
    ElseIf fld.Name = "x_coord" Then
    ElseIf fld.Name = "y_coord" Then
    Else
        str(i) = "SELECT cod_amb, '" & fld.Name & "' AS Param, " & fld.Name & " AS Val "
        i = i + 1
        ReDim Preserve str(i)
    End If
Next
Set fld = Nothing
i = 0
For i = 0 To UBound(str) - 1
    If i = 0 Then
        sqlAll = str(i) & "FROM " & tab & " UNION "
    ElseIf i > 0 And i < UBound(str) - 1 Then
        sqlAll = sqlAll & str(i) & "FROM " & tab & " UNION "
    ElseIf i = UBound(str) - 1 Then
        sqlAll = sqlAll & str(i) & "FROM " & tab & ";"
    End If
Next
Debug.Print sqlAll
End Sub

例程的输出是这样的字符串:

SELECT tab_011.cod_amb, "type_veg" AS Param, type_veg AS Val
FROM tab_011
UNION
SELECT tab_011.cod_amb, "type_acq" AS Param, type_acq AS Val
FROM tab_011
UNION
SELECT tab_011.cod_amb, "status" AS Param, status AS Val
FROM tab_011
UNION
SELECT tab_011.cod_amb, "num_pnt" AS Param, num_pnt AS Val
FROM tab_011
UNION
SELECT tab_011.cod_amb, "terr" AS Param, terr AS Val
FROM tab_011;

最后,我在Access中将此字符串作为Union Query运行,然后在Excel中导出生成的表 与上面显示的输出相比,结果表略有不同:不同之处在于列Val包含单个匹配而不是连接字符串。

2 个答案:

答案 0 :(得分:1)

如果你可以使用代码,这样的东西对你有用:

Dim rs As DAO.Recordset
Dim db As Database
Dim sql As String
Set db = CurrentDb()

Set rs = db.OpenRecordset("tblTable")

sql = ""
Dim fld As DAO.Field
For Each fld In rs.Fields
    If fld.Name <> "cod_amb" Then sql = sql + "SELECT cod_amb, '" + fld.Name + "' AS fldName, " + fld.Name + " AS fldValue FROM tblTable UNION "
Next
Set fld = Nothing

sql = Left(sql, Len(sql) - 6)

MsgBox (sql)

Form_tblTable.RecordSource = sql

rs.Close
Set rs = Nothing

答案 1 :(得分:0)

我不确定你是否可以在访问2007中使用PIVOT / UNPIVOT,如果不是你可以使用UNION查询... DECLARE表和插入只是为了使示例独立工作,你会使用自己的表

DECLARE @table TABLE (
    cod_amb int,
    field_a varchar(10),
    field_b varchar(10),
    field_c varchar(10),
    field_d varchar(10),
    field_e varchar(10))

INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural')
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'Conif','Temp','N.A.','>5 years','Artificial');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'N.A.','Fixed','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'NR','Fixed','N.A.','<5 years','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'N.A.','Temp','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural')

SELECT cod_amb, 'field_a' Field, field_a value FROM @table 
UNION
SELECT cod_amb, 'field_b' Field, field_b value FROM @table 
UNION
SELECT cod_amb, 'field_c' Field, field_c value FROM @table 
UNION
SELECT cod_amb, 'field_d' Field, field_d value FROM @table 
UNION
SELECT cod_amb, 'field_e' Field, field_e value FROM @table 

如果您有SQL Server可用(或者其他SQL服务器读者可以登陆),您将再次使用UNPIVOT ...,DECLARE表和插入只是为了使示例独立工作,您可以使用自己的表。

DECLARE @table TABLE (
cod_amb int,
field_a varchar(10),
field_b varchar(10),
field_c varchar(10),
field_d varchar(10),
field_e varchar(10))

INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural')
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'Conif','Temp','N.A.','>5 years','Artificial');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'N.A.','Fixed','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'NR','Fixed','N.A.','<5 years','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (24,'N.A.','Temp','N.A.','N.A.','Natural');
INSERT INTO @table(cod_amb,field_a,field_b,field_c,field_d,field_e)
VALUES (21,'N.A.','Fixed','N.A.','N.A.','Natural')


SELECT cod_amb, Field, Value
FROM 
   ( SELECT cod_amb,field_a,field_b,field_c,field_d,field_e FROM @table
   ) SourceTable
UNPIVOT
   (Value FOR Field IN 
      (field_a,field_b,field_c,field_d,field_e)
)AS unpvt;