4

可能重复:
Ms Access Query: Concatenating Rows through a query

我有一个有很多列的表,但有两个感兴趣:订单号和产品类型。目前,该表的每个订单有多个产品类型。如果客户订购了电话服务、电视服务和互联网服务,那么将有三份记录——每种服务一份,但都具有相同的订单号。我想创建一个引用表来存储与客户订购的所有服务的串联字符串。通过这种方式,我可以使用这种更合乎逻辑的方法来总结我的数据。我正在使用标准的 Access 2010 数据库。

**Current table:**

Order Number | Product Types

100001 | TV

100001 | Phone

100001 | Internet

100002 | Phone

100003 | TV

100003 | Internet

所需的参考表

100001 | TV/Phone/Internet

100002 | Phone

100003 | TV/Internet
4

4 回答 4

6

Allen Browne 提供了一个您可能会发现对此有用的函数:Concatenate values from related records。将该函数的代码保存在标准模块中。

SELECT DISTINCT
    [Order Number],
    ConcatRelated("[Product Types]",
        "YourTable",
        "[Order Number] = " & [Order Number],
        "[Product Types]",
        "/"
        ) AS All_Product_Types
FROM YourTable;

我在 Access 2007 中测试了该查询,您的示例数据保存在名为“ YourTable ”的表中。它返回了您要求的结果。但是,这仅适用于 Access 会话。如果您想从 Access 外部(如从 ASP)运行此查询,则用户定义的函数不可用,因此您会收到关于ConcatRelated()无法识别的错误。

因此,您可以在需要时使用查询来检索连接的值。但是,如果您存储这些连接的值,它们很快就会与基表数据的更改不同步。

于 2012-09-14T16:14:58.060 回答
1

If I understand the question, you're asking how to get the order numbers of just those orders who have TV, AND phone, AND internet. If you're just interested in those order numbers you could run a query like:

SELECT Distinct Table1.OrderNumber
FROM (Select OrderNumber from Table1 where [product types]= "Internet")  AS i
    INNER JOIN ((Select OrderNumber from Table1 where [product types]="Phone")  AS p 
    INNER JOIN ((Select OrderNumber from Table1 Where [product types]= "TV")  AS tv 
    INNER JOIN Table1 ON tv.OrderNumber = Table1.OrderNumber) ON p.OrderNumber = Table1.OrderNumber) ON i.OrderNumber = Table1.OrderNumber;
于 2012-09-14T16:20:54.587 回答
1

正如 onedaywhen 在 SO 的早期帖子中指出的那样,使用 ADO 更容易:示例查询:

   SELECT [Order Number], 
          ConcatADO("SELECT [Product Types] FROM Orders
                     WHERE [Order Number]=" & [Order Number],", "," : ") AS Cat
   FROM Orders
   GROUP BY [Order Number], 2;

使用 ADO 的函数

Function ConcatADO(strSQL As String, strColDelim, _
   strRowDelim, ParamArray NameList() As Variant)

   Dim rs As New ADODB.Recordset
   Dim strList As String

   On Error GoTo Proc_Err

       If strSQL <> "" Then
           rs.Open strSQL, CurrentProject.Connection
           strList = rs.GetString(, , strColDelim, strRowDelim)
           strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
       Else
           strList = Join(NameList, strColDelim)
       End If

       ConcatADO = strList

   Exit Function

   Proc_Err:
       ConcatADO = "***" & UCase(Err.Description)
End Function
于 2012-09-14T17:41:02.863 回答
0

您不应创建连接记录的引用表。那就是对数据库进行非规范化。

您可以尝试如下所示的交叉表查询,但我尚未对其进行测试。你可以在这里阅读更多信息。

TRANSFORM First([Product Types]) AS Product
SELECT [Order Number], First([Product Types])
FROM CurrentTable
GROUP [Order Number]
于 2012-09-14T16:01:32.960 回答