PDA

View Full Version : الحاق سطرهای جدول (Concatenating Rows) - به چه صورت جستجو کنم؟



reza_edu
یک شنبه 18 اردیبهشت 1390, 01:05 صبح
سلام به همه من مشکل نمایش اطلاعات 7 جدول رو داشتم که با روش گفته شده در سایت زیر حل شد عنوان شم این بود

صورت مساله

فرض کنید جدولی داریم که مشخصات دانشجویان را دربر گرفته است و جدول دیگر مشخصات دروس و جدولی دیگر دروس انتخاب شده توسط دانشجویان را نگه داری می کند. جدول دانشجو با جدول دروس انتخاب شده یک ارتباط 1 به چند (1-N) دارند و جدول داشنجو با جدول دروس یک ارتباط چند به چند دارند. در واقع جدول "دانشجو درس" جدول اتصال یا Junction Table نام دارد.

آدرس :http://www.30sharp.com/article/13/214/11/%D8%A7%D9%84%D8%AD%D8%A7%D9%82-%D8%B3%D8%B7%D8%B1%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%D9%88%D9%84-concatenating-rows.aspx
منم تو view از همین روش استفاده کردم حالا موندم تو این همه جدول چه جوری سرچ کنم(این سرچ باید بر اساس تک تک فیلد ها باشه و نتیجه نهائی تو همون ویو اولی که ساختم به کاربر نشون داده بشه :ناراحت: چه جوری سرچ کنم ؟ یه روش سرچ پویا تو این سایت بالا گفته شده ولی چه جوری دستور سلکتش رو بنویسم
از این روش ها هم استفاده کردم ولی جواب نگرفتم ؟

INTERSECT = اشتراک چند جدول

INNER JOIN : تمام رکوردهاي دو جدول، هر جا که شرط مطابقت داشته باشه نمايش داده ميشه
LEFT JOIN : تمام رکوردها از جدول اول نمايش داده ميشه، حتي اگر با هيچ رکوردي از جدول دوم مطابقت نداشته باشه.
RIGHT JOIN : تمام رکوردهاي جدول دوم رو نمايش ميده، حتي اگر با هم مطابقت نداشته باشند

محمد سلیم آبادی
یک شنبه 18 اردیبهشت 1390, 05:48 صبح
سلام،
اینطوری نمیشه مشکل رو بررسی کرد.
در صورت امکان view رو پست کنید و دقیقا مشخص کنید با مثال که چه نتیجه ای میخواد حاصل بشه و بر اساس چه پارامترهایی فیلتر صورت میگیره... .
اینو فراموش نکنید مشکلی نیست که حل نشه (حد اقل تو این بحث)

reza_edu
یک شنبه 18 اردیبهشت 1390, 10:17 صبح
در ابتدا ممنون از اینکه به سوال من توجه کردید .

بزارید مثال خود این سایت رو مطرح کنم ، فکر کنید ما بخوایم به کاربر این امکان رو بدیم که هم بر اساس ستون های جدول دانشجو و هم بر اساس ستون های جدول دروس جستجو کنه و نمایش نهائی بصورت
69667

باشه . خوب ممکنه کاربر درسی رو انتخاب کنه که همه دانشجو ها اون رو انتخاب کرده باشن . من تو نوشتن این دستور سلکت مشکل دارم البته نحوه نوشتن شرط WHERE این شرط به چه صورت باید اعمال بشه؟

محمد سلیم آبادی
یک شنبه 18 اردیبهشت 1390, 17:54 عصر
دقیقا مشخص نکردین چه فیلتری میخواهین صورت بگیره.
مثلا می خواهین یک درس یک کاربر رو در خروجی نمایش ندهد. یا اینکه با انتخاب یک درس کلا این درس به ازای تمام دانشجویان انتخاب نشه؟ دقیق تر توضیح بدین

مثلا اگه بخواهین فقط سطر مرتبط به David انتخاب بشه که کافیه یک WHERE اضافه بشه یعنی:

SELECT S.student_name, COALESCE(LEFT(D.list, LEN(D.list)-1), '') AS course_list
FROM Students AS S
CROSS APPLY (SELECT C.course_name + ', '
FROM StudentCourse SC
INNER JOIN Courses C
ON SC.course_nbr = C.course_nbr
WHERE SC.student_nbr = S.student_nbr
ORDER BY C.course_name ASC
FOR XML PATH('')) D(list)
WHERE S.student_name = 'David'
ORDER BY student_name;

یا اینکه می خواهین درس Math برای هیچ فردی انتخاب نشه:

SELECT S.student_name, COALESCE(LEFT(D.list, LEN(D.list)-1), '') AS course_list
FROM Students AS S
CROSS APPLY (SELECT C.course_name + ', '
FROM StudentCourse SC
INNER JOIN Courses C
ON SC.course_nbr = C.course_nbr
WHERE SC.student_nbr = S.student_nbr
AND C.course_name <> 'Mathmatics'
ORDER BY C.course_name ASC
FOR XML PATH('')) D(list)
ORDER BY student_name;

یا اینکه میخواهین فقط درس Math برای David انتخاب نشه:

SELECT S.student_name, COALESCE(LEFT(D.list, LEN(D.list)-1), '') AS course_list
FROM Students AS S
CROSS APPLY (SELECT C.course_name + ', '
FROM StudentCourse SC
INNER JOIN Courses C
ON SC.course_nbr = C.course_nbr
WHERE SC.student_nbr = S.student_nbr
AND (S.student_name <> 'David' OR (S.student_name = 'David' AND C.course_name <> 'Mathmatics'))
ORDER BY C.course_name ASC
FOR XML PATH('')) D(list)
ORDER BY student_name;

reza_edu
یک شنبه 18 اردیبهشت 1390, 18:39 عصر
سلام من با توجه به منابعی که در پایان مقاله ذکر شده بود دیدم که تنهاروشی که میشه این اجماع سطر ها رو تو یک view پیاده سازی کرد اینه که یه تابع بنویسم که با دادن کد کارمن به اون تابع اطلاعات مربوط به اون که تو یه جدول دیگه ذخیره میشه بصورت رشته برام برگردونه ، تابع نمونه در ذیل آورده شده :

USE [ExtentScience]
GO
/****** Object: UserDefinedFunction [dbo].[SumInfo_CognitionComputer] Script Date: 05/08/2011 18:49:20 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Batch submitted through debugger: SQLQuery1.sql|7|0|C:\Documents and Settings\Administrator\Local Settings\Temp\~vs166.sql
ALTER FUNCTION [dbo].[SumInfo_CognitionComputer]
(
@CodeRoot NVARCHAR(50)
)
RETURNS NVARCHAR(Max)
AS
BEGIN
DECLARE @StrResult NVARCHAR(Max),@Str NVARCHAR(Max),@CountCodeRoot INT ;
SET @CountCodeRoot =0;
SET @StrResult ='';

SELECT @CountCodeRoot = COUNT(*) FROM View_CognitionComputer WHERE CodeRoot = @CodeRoot ;

WHILE(@CountCodeRoot>0)
BEGIN

SELECT @Str = V1.ShowID_LevelCognitionComputer + ' - ' + V1.ShowID_TributaryComputer+ ' - ' + V1.Comment + ' // ' FROM View_CognitionComputer V1

WHERE CodeRoot = @CodeRoot AND @CountCodeRoot = ( SELECT COUNT(*) FROM View_CognitionComputer V2

WHERE V2.CodeRoot = V1.CodeRoot AND V2.ID_LevelCognitionComputer <= V1.ID_LevelCognitionComputer ) ;

SET @CountCodeRoot = (@CountCodeRoot - 1)

SELECT @StrResult = @Str + @StrResult

END


RETURN @StrResult;

END



من چند تابع مثل نمونه آورده شده نوشتم که این توابع رو در یک view که در ذیل کدش آورده شده بکار بردم :

SELECT dbo.View_FaPersonEmployee.CodeRoot, dbo.View_FaPersonEmployee.ID_TributaryUser, dbo.View_FaPersonEmployee.ImagePerson,
dbo.View_FaPersonEmployee.DateRegister, dbo.View_FaPersonEmployee.DateLastEdit, dbo.View_FaPersonEmployee.UserName,
dbo.View_FaPersonEmployee.Password, dbo.View_FaPersonEmployee.FirstName_FA, dbo.View_EnPersonEmployee.FirstName_EN,
dbo.View_FaPersonEmployee.LastName_FA, dbo.View_EnPersonEmployee.LastName_EN, dbo.View_FaPersonEmployee.Birthday_FA,
dbo.View_EnPersonEmployee.Birthday_EN, dbo.View_FaPersonEmployee.Gender_FA, dbo.View_EnPersonEmployee.Gender_EN,
dbo.View_FaPersonEmployee.Gender_FAShow, dbo.View_EnPersonEmployee.Gender_ENShow, dbo.View_FaPersonEmployee.StatusService_FA,
dbo.View_EnPersonEmployee.StatusService_EN, dbo.View_FaPersonEmployee.StatusService_FAShow,
dbo.View_EnPersonEmployee.StatusService_ENShow, dbo.View_FaPersonEmployee.FirstOfNationality_FA,
dbo.View_EnPersonEmployee.FirstOfNationality_EN, dbo.View_FaPersonEmployee.FirstOfNationality_FASho w,
dbo.View_EnPersonEmployee.FirstOfNationality_ENSho w, dbo.View_FaPersonEmployee.SeccondOfNationality_FA,
dbo.View_EnPersonEmployee.SeccondOfNationality_EN, dbo.View_FaPersonEmployee.SeccondOfNationality_FAS how,
dbo.View_EnPersonEmployee.SeccondOfNationality_ENS how, dbo.View_FaPersonEmployee.Religion_FA, dbo.View_EnPersonEmployee.Religion_EN,
dbo.View_FaPersonEmployee.Religion_FAShow, dbo.View_EnPersonEmployee.Religion_ENShow, dbo.View_FaPersonEmployee.Job_FA,
dbo.View_EnPersonEmployee.Job_EN, dbo.View_FaPersonEmployee.StatusMarrid_FA, dbo.View_EnPersonEmployee.StatusMarrid_EN,
dbo.View_FaPersonEmployee.StatusMarrid_FAShow, dbo.View_EnPersonEmployee.StatusMarrid_ENShow,
dbo.View_FaPersonEmployee.NumberOfChild_FA, dbo.View_EnPersonEmployee.NumberOfChild_EN,
dbo.View_FaPersonEmployee.IdentityNumber_FA, dbo.View_EnPersonEmployee.IdentityNumber_EN,
dbo.View_FaPersonEmployee.PlaceEmissionIdentity_FA , dbo.View_EnPersonEmployee.PlaceEmissionIdentity_EN ,
dbo.View_FaPersonEmployee.NationalCode_FA, dbo.View_EnPersonEmployee.NationalCode_EN, dbo.View_FaPersonEmployee.Passport_FA,
dbo.View_EnPersonEmployee.Passport_EN, dbo.View_FaPersonEmployee.HomePhone_FA, dbo.View_EnPersonEmployee.HomePhone_EN,
dbo.View_FaPersonEmployee.MobilPhone_FA, dbo.View_EnPersonEmployee.MobilPhone_EN, dbo.View_FaPersonEmployee.CodePostage_FA,
dbo.View_EnPersonEmployee.CodePostage_EN, dbo.View_EnPersonEmployee.AddressMail, dbo.View_FaPersonEmployee.HomeAddress,
dbo.View_FaDataStudy.LevelOfStudy_FA, dbo.View_EnDataStudy.LevelOfStudy_EN, dbo.View_FaDataStudy.LevelOfStudy_FAShow,
dbo.View_EnDataStudy.LevelOfStudy_ENShow, dbo.View_FaDataStudy.LastOfCertificate_FA, dbo.View_EnDataStudy.LastOfCertificate_EN,
dbo.View_FaDataStudy.PlaceOfLastCertificate_FA, dbo.View_EnDataStudy.PlaceOfLastCertificate_EN, dbo.View_FaDataStudy.AverageOfCertificat_FA,
dbo.View_EnDataStudy.AverageOfCertificat_EN, dbo.View_FaDataStudy.Attitude_FA, dbo.View_EnDataStudy.Attitude_En,
dbo.SUMInfo_DossierStudy(dbo.View_FaPersonEmployee .CodeRoot) AS SUM_DossierStudy,
dbo.SUMInfo_DidacticCourse(dbo.View_FaPersonEmploy ee.CodeRoot) AS SUM_DidacticCourse,
dbo.SumInfo_CognitionLanguage(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_CognitionLanguage,
dbo.SumInfo_CognitionComputer(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_CognitionComputer,
dbo.SUMInfo_DossierWorkPerson(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_DossierWorkPerson,
dbo.SumInfo_Family(dbo.View_FaPersonEmployee.CodeR oot) AS SUM_Family, dbo.View_FaPeacePerson.StatePeace,
dbo.View_FaPeacePerson.MaladyName, dbo.View_FaPeacePerson.InformationMalady, dbo.View_FaPeacePerson.DrugName,
dbo.View_FaPeacePerson.InformationDrug
FROM dbo.View_FaPersonEmployee LEFT OUTER JOIN
dbo.View_FaPeacePerson ON dbo.View_FaPersonEmployee.CodeRoot = dbo.View_FaPeacePerson.CodeRoot LEFT OUTER JOIN
dbo.View_FaDataStudy ON dbo.View_FaPersonEmployee.CodeRoot = dbo.View_FaDataStudy.CodeRoot LEFT OUTER JOIN
dbo.View_EnDataStudy ON dbo.View_FaPersonEmployee.CodeRoot = dbo.View_EnDataStudy.CodeRoot LEFT OUTER JOIN
dbo.View_EnPersonEmployee ON dbo.View_FaPersonEmployee.CodeRoot = dbo.View_EnPersonEmployee.CodeRoot


اون توابع اینها هستند :

dbo.SUMInfo_DossierStudy(dbo.View_FaPersonEmployee .CodeRoot) AS SUM_DossierStudy,
dbo.SUMInfo_DidacticCourse(dbo.View_FaPersonEmploy ee.CodeRoot) AS SUM_DidacticCourse,
dbo.SumInfo_CognitionLanguage(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_CognitionLanguage,
dbo.SumInfo_CognitionComputer(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_CognitionComputer,
dbo.SUMInfo_DossierWorkPerson(dbo.View_FaPersonEmp loyee.CodeRoot) AS SUM_DossierWorkPerson,
dbo.SumInfo_Family(dbo.View_FaPersonEmployee.CodeR oot) AS SUM_Family


خوب این view کاملا به درستی عمل میکنه و نیاز های من رو برا ورده میکنه اما مسئله اینجا هست که بر طبق سفارش استادم که این پرژه رو به من داده باید کاربر این امکان رو داشته باشه که بتونه بر اساس تکتک اطلاعات ذخیره شده در دیتابیس امکان جستجو داشته باشه تو روشی که شما در سایت ذکر شده توضیح داده بودید هیچ کدام از راه های گفته شده به دلیل داشتن شرت order by داخل view پیاده سازی نمیشدند {یا من بلد نبودم} اما بطور اتفاقی متوجه شدم که با استفاده از تابع میشه این عمل رو انجام داد ، که به درستی هم عمل میکنه ولی مشکل اینجا هست چه جوری یا به چه نحوی میشه شرط گذاشت که تو جدولی که ما اطلاعات اون رو بصورت رشته برگردوندیم مقدار ستون مورد نظر چک بشه:گریه::گریه:
مثال :
دوجدول داریم : 1. کارمند 2. اطلاعات اعضائ خانواده
تو جدول اول یه کارمند با کد کارمندی داریم که تو جدول دوم اطلاعات {ممکنه پدر-مادر-همسر-برادر} ذخیره شده باشه حالا فرض کنید که مدیر بخواد اطلاعات افرادی رو ببینه که اسم جد پدری اونها برابر "رضا" هست و ما برای نمایش اطلاعات کارمندان از روش گفته شده با یک view استفاده کردیم . این نکته مهم هست که اینجا view خیلی مهم هست و مدیر اطلاعات رو تو این ویو باید ببینه.

من به ذهنم این رسید که یه سلکت بنویسم با شرط مورد نظر که یه تعداد کد کارمندی برگردونه و باتوجه به کد کارمندی برگردونده شده مشابه اون تو ویو نشون داده بشه ولی تو نوشتن این دستورات موندم خواهشا کمک کنید:گریه: