次の3つのテーブルがあります。
すべてのリソース名のテーブルをGUIに表示したい。各行の1つのセルに、そのリソースのすべてのアプリケーション(コンマ区切り)をリストします。
すべてのリソースを取得する必要があり、各リソースのすべてのアプリケーションを取得する必要があるため、SQLでこれを行う最良の方法は何ですか?
最初にリソースからselect *を実行してから、各リソースをループし、リソースごとに個別のクエリを実行して、そのリソースのアプリケーションのリストを取得しますか?
1つのクエリでこれを行う方法はありますか?
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
そして、AppNameprogrammaticallyを連結し、ResNameでグループ化します。
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
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
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の文字列の集約/連結について読む をお勧めします。
SQL ServerでCOALESCEを使用してコンマ区切り文字列を作成する
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
データベースに依存しない方法でこれを行うための解決策があるかどうかはわかりません。なぜなら、おそらく何らかの形式の文字列操作が必要になるからです。それらは通常ベンダーによって異なります。
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 2005 FOR XML PATH
コンストラクトを使用して、サブアイテム(特定のリソースのアプリケーション)をコンマ区切りリストとしてリストします。
マーク
あなたが望むのは
SELECT ItemName, GROUP_CONCAT(DepartmentId) FROM table_name GROUP BY ItemName
MySQLを使用している場合
参照
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
取得するために次の方法で書くことができると思います(コードは単なる例であり、必要に応じて変更してください):
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
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
製品の以前のバージョンには、この問題に対する非常に多種多様な異なるアプローチがあります。それらの優れたレビューは記事にあります: Transact-SQLでの行値の連結 。
アイテムの数がわからない場合の値の連結
信頼できないアプローチ
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 Server
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;
Oracle
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;
これはSQL Serverでそれを行います:
DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Convert(nvarchar(8),DepartmentId)
FROM Table
SELECT @listStr
不可知論者であるために、ドロップバックしてパントします。
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_nameを連結します。r_nameは前回と同じです。