دمج نتائج متعددة في استعلام فرعي في قيمة واحدة مفصولة بفواصل
-
02-07-2019 - |
سؤال
لقد حصلت على جدولين:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
العلاقة هي صف واحد من TableA
- العديد من TableB
.
والآن أريد أن أرى نتيجة مثل هذه:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
لن ينجح هذا (نتائج متعددة في استعلام فرعي):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
هذه مشكلة تافهة إذا قمت بالمعالجة من جانب العميل.ولكن هذا يعني أنه سيتعين علي تشغيل استعلامات X في كل صفحة، حيث X هو عدد نتائج البحث TableA
.
لاحظ أنه لا يمكنني ببساطة إجراء عملية GROUP BY أو شيء مشابه، حيث إنها ستعرض نتائج متعددة لصفوف من TableA
.
لست متأكدًا مما إذا كان UDF، باستخدام COALESCE أو شيء مشابه قد يعمل؟
المحلول 2
1.إنشاء UDF:
CREATE FUNCTION CombineValues
(
@FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @SomeColumnList VARCHAR(8000);
SELECT @SomeColumnList =
COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = @FK_ID;
RETURN
(
SELECT @SomeColumnList
)
END
2.استخدم في الاستعلام الفرعي:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3.إذا كنت تستخدم الإجراء المخزن، فيمكنك القيام بذلك:
CREATE PROCEDURE GetCombinedValues
@FK_ID int
As
BEGIN
DECLARE @SomeColumnList VARCHAR(800)
SELECT @SomeColumnList =
COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB
WHERE FK_ID = @FK_ID
Select *, @SomeColumnList as SelectedIds
FROM
TableA
WHERE
FK_ID = @FK_ID
END
نصائح أخرى
وحتى هذا سوف يخدم هذا الغرض
بيانات العينة
declare @t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into @t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
استفسار:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM @T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM @T T1
GROUP BY id,Name
انتاج:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
أعتقد أنك على الطريق الصحيح مع COALESCE.انظر هنا للحصول على مثال لبناء سلسلة مفصولة بفواصل:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
في MySQL هناك group_concat الوظيفة التي ستعيد ما تطلبه.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
قد تحتاج إلى تقديم بعض التفاصيل الإضافية للحصول على إجابة أكثر دقة.
نظرًا لأن مجموعة البيانات الخاصة بك تبدو ضيقة نوعًا ما، فقد تفكر في استخدام صف لكل نتيجة وإجراء المعالجة اللاحقة على العميل.
لذا، إذا كنت تتطلع حقًا إلى جعل الخادم يقوم بالعمل، فارجع مجموعة نتائج مثل
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
وهو بالطبع عبارة عن INNER JOIN بسيط على المعرف
بمجرد حصولك على مجموعة النتائج مرة أخرى لدى العميل، احتفظ بمتغير يسمى CurrentName واستخدمه كمحفز عندما تتوقف عن تجميع SomeColumn في الشيء المفيد الذي تريده أن يفعله.
بافتراض أن لديك فقط عبارات WHERE في الجدول A، قم بإنشاء إجراء مخزن وبالتالي:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
ثم املأ DataSet ds به.ثم
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
وأخيرا يمكنك إضافة مكرر في الصفحة الذي يضع الفواصل لكل سطر
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
بهذه الطريقة ستفعل ذلك من جانب العميل ولكن باستخدام استعلام واحد فقط، وتمرير الحد الأدنى من البيانات بين قاعدة البيانات والواجهة الأمامية
لقد جربت الحل الذي ذكره priyanka.sarkar ولم ينجح تمامًا كما طلب OP.إليك الحل الذي انتهى بي الأمر إليه:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM @T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM @T T1
GROUP BY ID
الحل أدناه:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
استخدم هذا، يمكنك أيضًا تغيير عمليات الانضمام
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
سيعمل هذا على الاختيار من جدول مختلف باستخدام الاستعلام الفرعي.
لقد راجعت جميع الإجابات.أعتقد أن إدراج قاعدة البيانات يجب أن يكون مثل:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
يجب أن تكون الفاصلة في النهاية السابقة وقم بالبحث عن طريق الإعجاب %,X,%