Home > Enterprise >  SQL query to map data elements across columns in a table
SQL query to map data elements across columns in a table

Time:12-02

I have a 3 column table, and some columns have the same attributes. I want to return a table that shows which columns each attribute appears in. I am using SQL in Microsoft Access for this. How can I do this? Just an idea of where to start would be helpful as I do not have much SQL experience.

Table I have:

fruits1 fruits2 fruits3
apple banana lemon
banana cherry grape
lemon apple mango
orange grape banana

Table I want to return:

enter image description here

So far I have been doing this manually, and it is not working as the tables I am working with hold large data sets.

CodePudding user response:

You can use some VBA to do this. Something like:

Sub sUnpivot()
    On Error GoTo E_Handle
    Dim db As DAO.Database
    Dim rsSteer As DAO.Recordset
    Dim rsData As DAO.Recordset
    Dim rsLookup As DAO.Recordset
    Dim strSQL As String
    Set db = CurrentDb
' Start by getting a unique list across the 3 columns
    strSQL = "SELECT Fruits1 AS Fruits FROM tblPivot " _
        & " UNION SELECT Fruits2 FROM tblPivot " _
        & " UNION SELECT Fruits3 FROM tblPivot;"
    Set rsSteer = db.OpenRecordset(strSQL)
    If Not (rsSteer.BOF And rsSteer.EOF) Then
        db.Execute "DELETE * FROM tblUnpivot;"    ' get rid of old data
        Set rsData = db.OpenRecordset("SELECT * FROM tblUnpivot WHERE 1=2;")
        Do
            With rsData
                .AddNew
                !Attribute = rsSteer!Fruits
                strSQL = "SELECT COUNT(*) FROM tblPivot WHERE Fruits1='" & rsSteer!Fruits & "';"
                Set rsLookup = db.OpenRecordset(strSQL)
                If rsLookup(0) > 0 Then !Fruits1 = "x"
                strSQL = "SELECT COUNT(*) FROM tblPivot WHERE Fruits2='" & rsSteer!Fruits & "';"
                Set rsLookup = db.OpenRecordset(strSQL)
                If rsLookup(0) > 0 Then !Fruits2 = "x"
                strSQL = "SELECT COUNT(*) FROM tblPivot WHERE Fruits3='" & rsSteer!Fruits & "';"
                Set rsLookup = db.OpenRecordset(strSQL)
                If rsLookup(0) > 0 Then !Fruits3 = "x"
                .Update
            End With
            rsSteer.MoveNext
        Loop Until rsSteer.EOF
    End If
sExit:
    On Error Resume Next
    rsLookup.Close
    rsSteer.Close
    rsData.Close
    Set rsLookup = Nothing
    Set rsSteer = Nothing
    Set rsData = Nothing
    Set db = Nothing
    Exit Sub
E_Handle:
    MsgBox Err.Description & vvbcrlf & vbCrLf & "sUnpivot", vbOKOnly   vbCritical, "Error: " & Err.Number
    Resume sExit
End Sub

CodePudding user response:

We unpivot to get all the fruit types in one column and then pivot to group and mark them by fruit1, fruit2 and fruit3.

with t2 as 
(
          select fruits1 as fruit, 'fruits1' as col from t
union all select fruits2,          'fruits2'        from t
union all select fruits2,          'fruits3'        from t
)

select   fruit
        ,count(case when col = 'fruits1' then 1 end) as fruits1
        ,count(case when col = 'fruits2' then 1 end) as fruits2
        ,count(case when col = 'fruits3' then 1 end) as fruits3


from     t2
group by fruit
fruit fruits1 fruits2 fruits3
apple 1 1 1
banana 1 1 1
cherry 0 1 1
grape 0 1 1
lemon 1 0 0
orange 1 0 0

Fiddle

  • Related