Frage

Ich habe 3 Tabellen genannt:

  • Anwendungen (id, name)
  • Ressourcen (id, name)
  • ApplicationsResources (id, app_id, RESOURCE_ID)

Ich möchte auf einem GUI eine Tabelle aller Ressourcennamen zeigen. In einer Zelle in jeder Zeile würde Ich mag alle Anwendungen zur Liste aus (durch Komma getrennt) diese Ressource.

Die Frage ist also, was ist der beste Weg, dies in SQL zu tun, wie ich alle Ressourcen erhalten müssen, und ich muss auch für jede Ressource alle Anwendungen bekommen?

Habe ich eine wählen laufe * von Ressourcen und dann Schleife durch jede Ressource und hat eine separate Abfrage pro Ressource die Liste der Anwendungen für diese Ressource zu bekommen?

Gibt es eine Weise, die ich dies in einer Abfrage tun?

War es hilfreich?

Lösung

Es gibt keinen Weg, um es in ein DB-agnostische Weise zu tun. Sie müssen also die gesamten Daten-Set wie diese:

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

Und dann Concat die AppName programmatisch , während die Gruppierung von ResName .

Andere Tipps

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 Server (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('.','VARCHAR(max)'), 1, 1, '')
 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

Ich empfehle über String-Aggregation / concatentation in Oracle zu lesen.

COALESCE Mit Komma-separierte String in SQL Server Build
http://www.sqlteam.com/article/using -coalesce-to-build-kommagetrennte-string

Beispiel:

DECLARE @EmployeeList varchar(100)

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

SELECT @EmployeeList

Ich weiß nicht, ob es eine Lösung ist das in einer Datenbank-agnostische Weise zu tun, da Sie wahrscheinlich irgendeine Form von String-Manipulation benötigen, und diejenigen sind in der Regel unterschiedlich zwischen den Anbietern.

Für SQL Server 2005 und höher, könnten Sie verwenden:

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

Es verwendet den SQL Server 2005 FOR XML PATH Konstrukt, um die Unterpunkte Liste (die Anwendungen für eine bestimmte Ressource) als durch Kommata getrennte Liste.

Marc

Ich glaube, was Sie wollen, ist:

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

Wenn Sie mit MySQL

Referenz

Unter der Annahme, SQL Server:

Tabellenstruktur:

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

Abfrage:

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

Ergebnisse:

ItemName    DepartmentID
item1       21,13,9,36
item2       4,9,44

ich denke, wir in der folgenden Art und Weise schreiben kann abgerufen werden (Code unten ist nur ein Beispiel, bitte ändern je nach Bedarf):

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

nächste Version von SQL Server Sie in der Lage sein werden, tun

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 

Bei früheren Versionen des Produkts gibt es eine ganz große Vielfalt unterschiedlicher Ansätze für dieses Problem. Eine ausgezeichnete Bewertung von ihnen ist in dem Artikel: verketten Row Werte in Transact-SQL .

  • verketten Werte, wenn die Anzahl der Elemente nicht bekannt ist,

    • rekursive CTE Methode
    • Die Blackbox XML Methoden
    • Verwenden von Common Language Runtime
    • Scalar UDF mit Rekursion
    • Tabelle bewertet UDF mit einer while-Schleife
    • Dynamische SQL
    • Der Cursor Ansatz
      .
  • Nicht zuverlässige Ansätze

    • Scalar UDF mit T-SQL-Update-Erweiterung
    • Scalar UDF mit variabler Verkettung in SELECT

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;

Um Agnostiker, fallen zurück und Punt.

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;

Jetzt Benutzer Ihr Server Programmiersprache a_names verketten, während r_name das gleiche wie das letzte Mal ist.

Dies wird es in SQL Server tun:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Convert(nvarchar(8),DepartmentId)
FROM Table
SELECT @listStr
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top