English Deutsch Français Italiano Español Português 繁體中文 Bahasa Indonesia Tiếng Việt ภาษาไทย
All categories

Assume you have a table with two columns "Name" and "State".

Names can repeat in the table with different states. For example:

Name/State
Bob/NY
Bob/PA
Bob/VA

I want to write a SQL statement (without the use of cursors) that will return "Bob NY, PA, VA" on a single line.

Does anyone know of a way to do this in a straight SQL Statement?

Alternatively, any good tricks for accomplishing this using the functionality of Microsoft Access?

2006-07-27 13:45:16 · 3 answers · asked by jmofwiw 2 in Computers & Internet Programming & Design

3 answers

MySQL has GROUP_CONCAT, in MSSQL you can write a UDF that does some neat tricks.

In Access, you'd probably have to use VBA. The function that follows is a generic, and as such, suffers from a complete lack of optimization. If you're writing it to fill a special case, you can use static variables and collections to only have to look up data once. This function will make a request of the database for every row in the query (and sometimes more often--Access often runs code functions multiple times per row). It also assumes that the data coming in and the data coming out is textual.

'----------------
Function Group_Concat(Table As String, KeyField As String, KeyValue As Variant, ValueField As String, Optional Separator As String = ", ") As String
Dim sSQL As String
Dim rs As New ADODB.Recordset
Dim sResults() As String, iResultPosition As Integer

sSQL = "SELECT [" & ValueField & "] FROM [" & Table & "] WHERE [" & KeyField & "] "
If IsNull(KeyValue) Then
sSQL = sSQL & " Is Null"
Else
' Make sure we don't accidentally feed in SQL-breaking (or possibly SQL-injecting) quotes
' This makes it so a single quote character sent in is turned into a single-character wildcard
sSQL = sSQL & " Like '" & Replace(KeyValue, "'", "_") & "'"
End If

' Don't return Null values
sSQL = sSQL & " AND [" & ValueField & "] Is Not Null"

' Assume you want the data sorted
sSQL = sSQL & " ORDER BY [" & ValueField & "]"

' Nod toward optimization: By using a Static (or Keyset) recordset, we can find out how many rows
' are being returned, and use an array to store the contents of the row. VB bogs down heavily
' under string concatenation. However, if you're only expecting 3 or 4 results per request
' the array may be more overhead.

On Error Resume Next
rs.Open sSQL, CurrentProject.Connection, adOpenStatic, adLockReadOnly
If Err.Number <> 0 Then
' Catch errors and return them as the result
Group_Concat = "#ERROR#: (" & CStr(Err.Number) & ") " & Err.Description
Exit Function
End If
On Error GoTo 0

If rs.RecordCount = 0 Then
rs.Close
Exit Function
End If

ReDim sResults(0 To rs.RecordCount - 1)
Do Until rs.EOF
sResults(iResultPosition) = rs.Fields(ValueField).Value

iResultPosition = iResultPosition + 1
rs.MoveNext
Loop
rs.Close

Group_Concat = Join(sResults, Separator)
End Function
'-----------------

Sample SQL, assuming a table called tblNamesStates with two columns: Name, and State

SELECT
Name
, Group_Concat( "tblNamesStates", "Name", [Name], "State" )
FROM tblNamesStates
GROUP BY Name

Hope that helps.

2006-07-27 19:23:16 · answer #1 · answered by Hulett H 2 · 0 0

I know there is a CONCAT function in MySQL, but not sure if this works in Access

2006-07-27 21:04:54 · answer #2 · answered by shadowkat 5 · 0 0

To do it in mysql you would use:
SELECT name, GROUP_CONCAT(state) FROM table GROUP BY name

my mistake the command was GROUP_CONCAT

2006-07-27 21:10:14 · answer #3 · answered by John J 6 · 0 0

fedest.com, questions and answers