1

何を検索すればよいかさえわからないので、これがすでにどこかでカバーされている場合はご容赦ください。

複数のテーブルからデータを取得する SELECT ステートメントがあります。予想どおり、このクエリを実行すると、次のように、2 番目のテーブルの各レコードのレコードが取得されます。

|ID     |Name     |Assets
 ------------------------------------
|1      |Bob      |Car
|1      |Bob      |Bicycle
|1      |Bob      |House
|2      |Jane     |Car
|2      |Jane     |House
|3      |Peter    |Boat
|3      |Peter    |Car
|3      |Peter    |Motorcycle

私が欲しいのは次のようなものです:

|ID     |Name     |Assets
 ------------------------------------
|1      |Bob      |Car,Bicycle,House
|2      |Jane     |Car,House
|3      |Peter    |Boat,Car,Motorcycle

PHP を使用して、最初のテーブルから取得したレコードごとに 2 回データベースにヒットするだけでこれを達成できましたが、ページの更新ごとにデータベースに 40 ~ 60 回ヒットするため、ページが遅くなります。

クエリ 1:

SELECT ID,Name FROM People

次に、while ループ内でクエリ 2 を実行します。

<?php
while($owner_row=odbc_fetch_array($query1) {
$assets = odbc_exec($conn,"SELECT Asset FROM Assets WHERE Owner='$owner_row[Name]'");
$asset_array = odbc_fetch_array($assets);
$asset_string = implode(",",$asset_array);
}

次に、各所有者からのアセットの結果を文字列に結合し、好きなように表示できます。

単一のクエリでこれを達成する方法はありますか?データベースに一度だけヒットし、それらのアセットをクエリ自体内の単一の値に結合する方法はありますか?

4

3 に答える 3

3

どのデータベースにヒットしているのかわかりませんが、mySQL を使用している場合は、これを行う group_concat という素敵な関数があり、次のように機能します。

select 
    a.ID, 
    a.Name, 
    group_concat(b.Asset) as assetGroup 
from 
    people a
        join Assets b
            on a.ID=b.Owner 
group by 
    a.ID, 
    a.Name

正確に出力されるもの:

|ID     |Name     |Assets
 ------------------------------------
|1      |Bob      |Car,Bicycle,House
|2      |Jane     |Car,House
|3      |Peter    |Boat,Car,Motorcycle

編集: テーブル people の各レコードには、Assets テーブルに少なくとも 1 つの一致するレコードがあると想定しています。そうでない場合は、クエリで代わりに外部結合を使用します。

編集:私はSyBaseに精通していませんが、関連する関数をすばやく検索すると、悪いニュースが得られました.MYSQL group_concatはSybase ASEで同等ですか? SyBase にはこのような関数はありません。結果を取得するには、ストアド プロシージャを作成する必要がありますが、(はるかに難しい方法ではありますが) データベースで直接これを実行できることを示しています。

ストアド プロシージャを記述したくない場合でも、クエリでテーブルを結合し、ID ごとに多くの行を PHP に返し、次の行に沿って単純にループすることができます。

$currentID=0;
$userAssets=array();
while($row=$AnotherRowFromTheDatabase)
{
    if($row['ID']==$currentID)
    {
        $userAssets[]=$row['Asset'];
    }
    else
    {
        $currentID=$row['ID'];
        // More stuff to move the array previously
        // and start a new Assets Array
    }
}
于 2012-09-12T01:35:53.110 に答える
0

ここでは、Sybase LIST関数を使用します。

例えば

SELECT ID,NAME,LIST(ASSETS)
FROM PEOPLE
GROUP BY ID,NAME
于 2012-09-12T03:19:08.310 に答える
-1

以下の SQL を使用してください。

declare @tempUser  Table
(
ID int,
Name nvarchar(250),
AssetNAme nvarchar(250)
)
Insert into @tempUser values(1,'Bob','Car')
Insert into @tempUser values(1,'Bob','Bicycle')
Insert into @tempUser values(1,'Bob','House')
Insert into @tempUser values(2,'Jane','Car')
Insert into @tempUser values(2,'Jane','House')
Insert into @tempUser values(3,'Peter','Boat')
Insert into @tempUser values(3,'Peter','Car')
Insert into @tempUser values(3,'Peter','MotorCycle')


select  tt.ID,tt.Name,(select ITT.AssetNAme + ', ' as 'data()'  from @tempUser as ITT 
where ITT.ID =tt.ID for xml path('')) from @tempUser  as tt group by tt.ID,tt.Name
于 2012-09-12T05:07:25.647 に答える