0

私のデータベースでは、[Customer]テーブルと[Car]テーブルの間に1対多の関係があり、1人の顧客が0台以上の車を所有している可能性があります。

私のプロジェクトでは、すべての顧客のリストを、車からの車両登録[VehicleReg]を示す単一の列とともに出力する必要があります。顧客が複数の車を所有している場合、すべての車両登録はコンマで区切って表示する必要があります。顧客が車を持っていない場合、列は空白にする必要があります。

これがクエリの基本ですが、登録番号を返す方法がわかりません。

SELECT [Customer]。[FirstName]、[CustomerLastName]、COMMA SEPARATED VEHICLE REGS FROM [Customer] LEFT JOIN [Car]ON[Customer]。[CustomerId]=[Car]。[fkCustomerId]

私が探している出力は次のようになります

FirstName   | LastName    | VehicleRegistrations
-------------------------------------------------
John        | Smith       | MY51 4RT
Joe         | Mason       | MU08 5TH
Connor      | Norman      |
Graham      | Naughton    | HT09 6TY, HT11 8UQ
Lilly       | Adams       | JK55 8HY

MS Access 1997データベース、C#および.NET4.0を使用しています。

この段階では、パフォーマンスは大きな問題ではありません。

私がこれまでに持っている唯一の有効な解決策は、車両登録を[顧客]テーブルの列に保存することです。これは機能しますが、[Car]テーブルの車両登録に加えられた変更と新しい列を手動で同期させる必要があります。これはそれほど難しくはありませんが、プロジェクトを他の人に渡すと危険なアプローチになる可能性があります。維持する。

どうもありがとう

4

2 に答える 2

1

You need a helper function in order to achieve this

Public Function JoinFromRecordset( _
    DataSource As String, Optional Delimiter As String = ";", _
    Optional Columns As Long = 1) As String

    Dim db As DAO.Database, rs As DAO.Recordset, s As String, col As Long

    Set db = CurrentDb
    Set rs = db.OpenRecordset(DataSource, dbOpenForwardOnly)
    Do Until rs.EOF
        For col = 0 To Columns - 1
            If s = "" Then
                s = Nz(rs(col))
            Else
                s = s & Delimiter & Nz(rs(col))
            End If
        Next col
        rs.MoveNext
    Loop
    rs.Close: Set rs = Nothing
    db.Close: Set db = Nothing
    JoinFromRecordset = s
End Function

Now you can write

SELECT FirstName, CustomerLastName,
    JoinFromRecordset('SELECT VehicleReg FROM Car WHERE fkCustomerId=' & 
        CustomerId) As VehicleRegistrations
FROM Customer
于 2012-06-26T14:36:05.187 に答える
0

データベースをそのままにして、アプリケーションでレポート操作を実行します。以下で行った方法と同様に、Northwind データベースを使用して Customers を Orders に結合し、Reg Number の代わりに Order Id を使用します。

2 つのクラスを作成します。

public class Customer
{
    public string Name { get; set; }
    public IEnumerable<Order> Orders { get; set; }
}

public class Order
{
    public int Id { get; set; }
}

Customers と Orders のデータ テーブルと外部キーのテーブル間の関係を使用して、データのデータセットを作成します。型指定されたデータセットを使用してアダプターの作成を自動化しましたが、手動で作成する場合も同じ原則が適用されます。

データを取得して配置する ViewModel クラスを作成します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SO_StringAggregate
{
    public class ViewModel
    {
        public ViewModel()
        {
            // populate the data set
            var dataSet = new NorthwindDataSet();
            using (var customersAdp = new NorthwindDataSetTableAdapters.CustomersTableAdapter())
            using (var ordersAdp = new NorthwindDataSetTableAdapters.OrdersTableAdapter())
            {
                customersAdp.Fill(dataSet.Customers);
                ordersAdp.Fill(dataSet.Orders);
            }

            // populate your domain objects
            var customers = dataSet.Customers.ToArray().Select(cust => new Customer
            {
                Name = cust.Company_Name,
                Orders = cust.GetOrdersRows().Select(order => new Order { Id = order.Order_ID })
            });

            this.Customers = customers;

            // build the report
            StringBuilder report = new StringBuilder();
            string formatString = "{0,-30}|{1}";

            report.Append(string.Format(formatString, "Name", "Order Ids"));
            report.Append(Environment.NewLine);
            Customers.ToList().ForEach(cust => report.AppendLine(string.Format(
                formatString, 
                cust.Name, 
                string.Join(",", cust.Orders.Select(o => o.Id).ToArray()))
                ));

            // display the report
            Report = report.ToString();
        }

        public IEnumerable<Customer> Customers { get; set; }

        public string Report { get; set; }

    }
}

その後、Report プロパティにバインドされたビューにデータを表示できます。

<Window x:Class="SO_StringAggregate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox FontFamily="Consolas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding Report}" />
    </Grid>
</Window>
于 2012-06-26T14:58:08.953 に答える