60

次の 3 つのテーブルがあります。

  • アプリケーション (ID、名前)
  • リソース (ID、名前)
  • アプリケーションリソース (id、app_id、resource_id)

すべてのリソース名のテーブルを GUI に表示したいと考えています。各行の 1 つのセルに、そのリソースのすべてのアプリケーション (カンマ区切り) を一覧表示したいと思います。

問題は、すべてのリソースを取得する必要があり、各リソースのすべてのアプリケーションも取得する必要があるため、SQL でこれを行う最善の方法は何ですか?

最初に select * from resources を実行してから、各リソースをループし、リソースごとに個別のクエリを実行して、そのリソースのアプリケーションのリストを取得しますか?

1 つのクエリでこれを行う方法はありますか?

4

11 に答える 11

133

MySQL

  SELECT r.name,
         GROUP_CONCAT(a.name SEPARATOR ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

SQL サーバー (2005 以降)

SELECT r.name,
       STUFF((SELECT ',' + a.name
               FROM APPLICATIONS a
               JOIN APPLICATIONRESOURCES ar ON ar.app_id = a.id
              WHERE ar.resource_id = r.id
           GROUP BY a.name
            FOR XML PATH(''), TYPE).value('text()[1]','NVARCHAR(max)'), 1, LEN(','), '')
 FROM RESOURCES r

SQL Server (2017+)

  SELECT r.name,
         STRING_AGG(a.name, ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

オラクル

Oracle での文字列の集約/連結について読むことをお勧めします。

于 2009-11-30T05:55:11.643 に答える
34

ノート:

この方法は、不正確または非決定論的な結果をもたらす可能性があるため、お勧めしません。
これは、StackOverflowおよびDBAで文書化されています。

COALESCE を使用して SQL Server
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-stringでコンマ区切り文字列を作成する

例:

DECLARE @EmployeeList varchar(100)

SELECT @EmployeeList = COALESCE(@EmployeeList + ', ', '') + 
   CAST(Emp_UniqueID AS varchar(5))
FROM SalesCallsEmployees
WHERE SalCal_UniqueID = 1

SELECT @EmployeeList
于 2009-11-30T05:38:52.940 に答える
11

データベースに依存しない方法でこれを行うための解決策があるかどうかはわかりません。おそらく、何らかの形式の文字列操作が必要になる可能性が高く、それらは通常ベンダー間で異なるためです。

SQL Server 2005 以降では、次を使用できます。

SELECT
     r.ID, r.Name,
     Resources = STUFF(
       (SELECT ','+a.Name
        FROM dbo.Applications a
        INNER JOIN dbo.ApplicationsResources ar ON ar.app_id = a.id
        WHERE ar.resource_id = r.id
        FOR XML PATH('')), 1, 1, '')
FROM
     dbo.Resources r

SQL Server 2005FOR XML PATHコンストラクトを使用して、サブ項目 (特定のリソースのアプリケーション) をカンマ区切りのリストとしてリストします。

マルク

于 2009-11-30T05:51:54.207 に答える
5

SQL Serverを想定しています:

テーブル構造:

CREATE TABLE [dbo].[item_dept](
    [ItemName] char(20) NULL,
    [DepartmentID] int NULL   
)

クエリ:

SELECT ItemName,
       STUFF((SELECT ',' + rtrim(convert(char(10),DepartmentID))
        FROM   item_dept b
        WHERE  a.ItemName = b.ItemName
        FOR XML PATH('')),1,1,'') DepartmentID
FROM   item_dept a
GROUP BY ItemName

結果:

ItemName    DepartmentID
item1       21,13,9,36
item2       4,9,44
于 2010-06-21T19:25:22.633 に答える
5

あなたが望むものは次のとおりだと思います:

SELECT ItemName, GROUP_CONCAT(DepartmentId) FROM table_name GROUP BY ItemName

MySQL を使用している場合

参照

于 2010-06-21T19:22:03.373 に答える
4

以下のように書けば取得できると思います(以下のコードは一例ですので、必要に応じて変更してください)。

Create FUNCTION dbo.ufnGetEmployeeMultiple(@DepartmentID int)
RETURNS VARCHAR(1000) AS

BEGIN

DECLARE @Employeelist varchar(1000)

SELECT @Employeelist = COALESCE(@Employeelist + ', ', '') + E.LoginID
FROM humanresources.Employee E

Left JOIN humanresources.EmployeeDepartmentHistory H ON
E.BusinessEntityID = H.BusinessEntityID

INNER JOIN HumanResources.Department D ON
H.DepartmentID = D.DepartmentID

Where H.DepartmentID = @DepartmentID

Return @Employeelist

END

SELECT D.name as Department, dbo.ufnGetEmployeeMultiple (D.DepartmentID)as Employees
FROM HumanResources.Department D

SELECT Distinct (D.name) as Department, dbo.ufnGetEmployeeMultiple (D.DepartmentID) as 
Employees
FROM HumanResources.Department D
于 2012-09-25T03:31:31.923 に答える
4

次のバージョンの SQL Serverから、次のことが可能になります。

SELECT r.name,
       STRING_AGG(a.name, ',')
FROM   RESOURCES r
       JOIN APPLICATIONSRESOURCES ar
         ON ar.resource_id = r.id
       JOIN APPLICATIONS a
         ON a.id = ar.app_id
GROUP  BY r.name 

製品の以前のバージョンでは、この問題に対して非常に多種多様なアプローチがありました。それらの優れたレビューは、次の記事にあります: Concatenating Row Values in Transact-SQL .

  • 項目数がわからない場合の値の連結

    • 再帰的 CTE メソッド
    • ブラックボックスの XML メソッド
    • 共通言語ランタイムの使用
    • 再帰を伴うスカラー UDF
    • WHILE ループを使用したテーブル値 UDF
    • 動的 SQL
    • カーソルアプローチ
  • 信頼できないアプローチ

    • t-SQL 更新拡張機能を使用したスカラー UDF
    • SELECT での変数連結を伴うスカラー UDF
于 2010-06-25T20:35:01.490 に答える
2

MySQL

  SELECT r.name,
         GROUP_CONCAT(a.name SEPARATOR ',')
    FROM RESOURCES r
    JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
    JOIN APPLICATIONS a ON a.id = ar.app_id
GROUP BY r.name

**


MS SQL サーバー

SELECT r.name,
       STUFF((SELECT ','+ a.name
               FROM APPLICATIONS a
               JOIN APPLICATIONRESOURCES ar ON ar.app_id = a.id
              WHERE ar.resource_id = r.id
           GROUP BY a.name
            FOR XML PATH(''), TYPE).value('.','VARCHAR(max)'), 1, 1, '')
 FROM RESOURCES r
 GROUP BY deptno;

オラクル

  SELECT r.name,
         LISTAGG(a.name SEPARATOR ',') WITHIN GROUP (ORDER BY a.name)
  FROM RESOURCES r
        JOIN APPLICATIONSRESOURCES ar ON ar.resource_id = r.id
        JOIN APPLICATIONS a ON a.id = ar.app_id
  GROUP BY r.name;
于 2016-04-20T08:04:41.367 に答える
1

不可知論者になるには、後退してパントします。

Select a.name as a_name, r.name as r_name
  from ApplicationsResource ar, Applications a, Resources r
 where a.id = ar.app_id
   and r.id = ar.resource_id
 order by r.name, a.name;

ここで、サーバー プログラミング言語を使用して a_names を連結しますが、r_name は前回と同じです。

于 2009-11-30T05:56:40.953 に答える
1

これはSQL Serverでそれを行います:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Convert(nvarchar(8),DepartmentId)
FROM Table
SELECT @listStr
于 2010-06-21T19:20:12.177 に答える
0

DBにとらわれない方法でそれを行う方法はありません。したがって、次のようにデータセット全体を取得する必要があります。

select 
  r.name as ResName, 
  a.name as AppName
from 
  Resouces as r, 
  Applications as a, 
  ApplicationsResources as ar
where
  ar.app_id = a.id 
  and ar.resource_id = r.id

次に、 ResNameでグループ化しながらAppNameを プログラムで連結します。

于 2009-11-30T06:03:24.137 に答える