كيف أقوم بإنشاء قائمة مفصولة بفواصل باستخدام استعلام SQL؟

StackOverflow https://stackoverflow.com/questions/1817985

سؤال

لدي 3 جداول تسمى:

  • التطبيقات (المعرف، الاسم)
  • الموارد (المعرف، الاسم)
  • مصادر التطبيقات (المعرف، app_id، الموارد_id)

أريد أن أعرض على واجهة المستخدم الرسومية جدولًا بجميع أسماء الموارد.في خلية واحدة في كل صف، أود سرد كافة التطبيقات (مفصولة بفواصل) لهذا المورد.

لذا فإن السؤال هو، ما هي أفضل طريقة للقيام بذلك في SQL حيث أحتاج إلى الحصول على جميع الموارد وأحتاج أيضًا إلى الحصول على جميع التطبيقات لكل مورد؟

هل أقوم بتشغيل تحديد * من الموارد أولاً ثم تكرار كل مورد وإجراء استعلام منفصل لكل مورد للحصول على قائمة التطبيقات لهذا المورد؟

هل هناك طريقة يمكنني من خلالها القيام بذلك في استعلام واحد؟

هل كانت مفيدة؟

المحلول

لا توجد طريقة للقيام بذلك بطريقة حيادية لقاعدة البيانات.لذلك تحتاج إلى الحصول على مجموعة البيانات بأكملها مثل هذا:

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.

نصائح أخرى

ماي إس كيو إل

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

خادم SQL (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.

استخدام 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

لا أعرف ما إذا كان هناك أي حل للقيام بذلك بطريقة لا تعتمد على قاعدة البيانات، نظرًا لأنك ستحتاج على الأرجح إلى شكل من أشكال معالجة السلسلة، وعادةً ما يختلف ذلك بين البائعين.

بالنسبة لـ 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:

هيكل الجدول:

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.

  • تسلسل القيم عندما يكون عدد العناصر غير معروف

    • طريقة CTE العودية
    • أساليب الصندوق الأسود XML
    • استخدام وقت تشغيل اللغة العامة
    • UDF العددية مع العودية
    • جدول بقيمة UDF مع حلقة WHILE
    • SQL الديناميكية
    • نهج المؤشر
      .
  • أساليب غير موثوقة

    • Scalar UDF مع ملحق تحديث t-SQL
    • UDF عددي مع تسلسل متغير في SELECT

ماي إس كيو إل

  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;

لكي تكون ملحدًا، قم بالتراجع والقفز.

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 هو نفسه في المرة الأخيرة.

سيتم ذلك في SQL Server:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' ,'') + Convert(nvarchar(8),DepartmentId)
FROM Table
SELECT @listStr
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top