ورود

View Full Version : جستجوي اسامي تكراري در جدول



fadak 64
یک شنبه 18 مهر 1389, 09:45 صبح
سلام
يه جدول دارم با يه فيلد يونيك به نام شماره پرونده. در اين جدول ممكن است يك نفر چندين شماره پرونده داشته باشد چگونه اسامي تكراري را در اين جدول به دست بيارم.(چون داده هام زياده سورت جواب نميده) فانكشن نويسي بلد نيستم.ممنون

tooraj_azizi_1035
یک شنبه 18 مهر 1389, 11:18 صبح
سلام
يه جدول دارم با يه فيلد يونيك به نام شماره پرونده. در اين جدول ممكن است يك نفر چندين شماره پرونده داشته باشد چگونه اسامي تكراري را در اين جدول به دست بيارم.(چون داده هام زياده سورت جواب نميده) فانكشن نويسي بلد نيستم.ممنون

سلام، اگه علاوه بر نام مثلاً نام خانوادگی و آدرس و فیلد های اضافی دیگه هم برای دو شماره پرونده که متعلق به یک شخص هست رو تو جدول ذخیره کردی جدول دارای افزونگی داده هست. شما اشخاص رو تو یه جدول قرار بده و مشخصات پرونده رو تو یه جدول دیگه قرار بده و تو جدول پرونده با یه کد صاحب اون رو مشخص کن. در مورد پیدا کردن اسامی تکراری باید بگم که تو جدول باید یه اسم بدی تا پرونده های اون اسم رو Query برات بیاره. در نهایت بهترین راه اینه که شما جدول موجود رو به دو جدول که رابطه یک به چند بین اون دو برقراره بشکنی: اشخاص سمت "یک" رابطه و پرونده در سمت "چند" رابطه.
بعد از این کار تو Query Designer جداول رو Add کن و تو ستون اسم مقدار مورد نظر رو وارد کن تا اسامی تکراری (یعنی همنام) رو برات لیست کنه.
امیدوارم منظورت رو درست متوجه شده باشم. :بوس:

fadak 64
یک شنبه 18 مهر 1389, 15:10 عصر
سلام ممنون از پاسختون- امكان اينكه بخام دوتا جدولش كنم نيست .تو جدولم حدود 50هزار نفر ثبت نام آزمون دارم كه براي هر ثبت نام يك شماره پرونده دارن، من ميخوام بدونم هر نفر چندبار آزمون شركت كرده در واقع چند تا شماره پرونده داره . چون تعداد ركوردام زياده امكان اينكه بخام دونه دونه اسم بدم نيست . از سلكت هاي تودر تو هم استفاده كردم اما چون تعداد ركوردام زياده جواب دقيق بهم نميده . ممنون ميشم اگه بيشتر راهنماييم كنيد

tooraj_azizi_1035
یک شنبه 18 مهر 1389, 15:30 عصر
سلام،
1. ببینید شما اگه دنبال اسامی که بیش از یک شماره پرونده به آنها اختصاص داده شده هستید (اگه می شه هدفتون رو از این کار بگید) و از این Query تو یه برنامه بخوایین استفاده کنین یا اینکه بخوایین دستی کاری رو جدول انجام بدید بالاخره باید یک اسم تو قسمت WHERE کد SQL بدید. این یه موضوع روشنه. یعنی باید بگید چی می خواید تا نتیجه ای به شما نمایش داده بشه. بعد از بدست آوردن نتیجه SQL از تابع COUNT برای بدست آوردن تعداد رکوردها که همون تعداد پرونده ها برای یه اسم خاص هست (البته اسم می تونه برای دو نفر باشه سعی کن فیلدهای بیشتری رو تو جستجو شرکت بدی)استفاده کن.
2. منظورتون از اینکه سورت جواب نمی ده چیه؟
3.
در مورد اینکه نمی تونید جدول رو بشکونید باید بگم می شه از یه Make Table Qurey برای ساخت یه جدول استفاده کنی. اگه این مورد رو ترجیح می دی تو پست بعدی بگم چی کار کنی.
امیدوارم کمکت کنه.

Reza_Yarahmadi
یک شنبه 18 مهر 1389, 22:19 عصر
يه جدول دارم با يه فيلد يونيك به نام شماره پرونده. در اين جدول ممكن است يك نفر چندين شماره پرونده داشته باشد چگونه اسامي تكراري را در اين جدول به دست بيارم.(چون داده هام زياده سورت جواب نميده) فانكشن نويسي بلد نيستم.ممنون
با group by میتونید این کار رو انجام بدید

Select
FirstName
,LastName
,MeliCode
From TableName
Group By
FirstName
,LastName
,MeliCode
Having Count(*) > 1
توی این دستور 3 فیلد نام و نام خانوادگی و شماره ملی برمیگردونه
به روش زیر هم میشه این کار رو انجام داد ولی به شرطی که فیلدی مثل کد ملی داشته باشید.

with temp as(Select
Min(DocumentId) as ID
From TableName
Group By
MeliCode
Having Count(*) > 1)
Select
TableName.*
From TableName n inner Join temp t
on n.DocumentId = t.ID
( منظور از DocumentId همون شماره پرونده است)
البته روشهای دیگه ای هم هست

fadak 64
دوشنبه 19 مهر 1389, 09:42 صبح
سلام ممنون از راهنمائيتون جواب گرفتم . فقط اگه لطف كنيد كد دوم رو توضيح بدين ممنون ميشم(temp)

حمیدرضاصادقیان
دوشنبه 19 مهر 1389, 10:11 صبح
سلام. به روش دوم میگویند CTE که از نسخه 2005 به بعد قرار داده شد.
که در این لینک (http://msdn.microsoft.com/en-us/library/ms190766.aspx) درموردش توضیح داده شده است.
موفق باشید

Reza_Yarahmadi
دوشنبه 19 مهر 1389, 10:11 صبح
توي روش دوم اول كمترين شماره پرونده كساني كه بيشتر از يك ركورد دارند به وسيله دستور with توي temp ريخته ميشه بعدش مشخصات كامل با توجه به اين شماره پرونده ها با يك join بدست مياد. چون شماره پرونده ها يونيك هستند و تمام شماره پرونده هاي temp مربوط به كساني هستند كه بيشتر از يك ركورد دارند پس اطالاعات مورد نظر بدست مياد.
چون حدس ميزنم با دستور with مشكل داشته باشيد يك مقدار در مورد اون هم توضيح ميدم.
با اين دستور ميتونيد براي يك جستجو اسم تعيين كنيد و توي جستجوي ديگه اي ازش استفاده كنيد
اگه بخوايد چند with تعريف كنيد بايد پشت سر هم باشند و بينشون دستور ديگه اي نباشه ، با "،" از هم جدا ميشن

with h1 as(
Select
'Temp' as T
)
, h2 as(
Select
'Temp2' as T2
,T
from h1
)
,h3 as (
Select
'Temp3' as T3
,*
From h2
)
Select * from h3
بايد توي دستور بعد از آخرين with از يكي از withها حتما استفاده بشه (وگر نه خطا ميده). فقط در دستور بعد از آخرين with ميتونيد از withها استفاده كنيد و بعد از اون ديگه نميشه استفاده كرد.
with بايد اول يك بچ كد باشه (يعني اينكه يا قبل از شروعش دستوري نباشه و يا اينكه قبل از with يك ";" بذاريد.

اميدوارم اين توضيحات بتونه كمكتون كنه.

SQL DEVELOP
چهارشنبه 05 آبان 1389, 09:17 صبح
با تشکر از همه دوستان بخصوص Reza_Yarahmadi که راه حل اول ایشان مشابه یکی از راه حل های من است، در دو پست زیر در وبلاگم شناسایی و حذف داده های تکراری را توضیح داده ام:
http://sqldevelop.wordpress.com/2010/07/09/how-to-identify-duplicate-records-in-sql-server/
http://sqldevelop.wordpress.com/2010/09/13/delete-duplicate-rows-in-sql-server/

ولی دیشب راه حل جالبی برای حذف داده های تکراری به ذهنم رسید:


DELETE T1 FROM
(SELECT
id, ROW_NUMBER() OVER(ORDER BY id) RowNum
FROM Tbl) T1
JOIN
(SELECT
id, ROW_NUMBER() OVER(ORDER BY id) RowNum
FROM Tbl) T2
ON
T1.id=T2.id
AND
T1.RowNum<T2.RowNum

Rezahak
چهارشنبه 05 آبان 1389, 13:26 عصر
اين راه حل شما از نظر زماني يك فاجعه است و اصلا optimize نيست بهترين راه استفاده از Group by يا with است(به نظر من group by بهتر است ولي دوستان در مورد بهينه بودن نظر بدهند لطفا)

SQL DEVELOP
چهارشنبه 05 آبان 1389, 21:56 عصر
rezahak عزیز
ممنون از دقت نظتون
من به لحاظ منطقی از این کد لذت بردم.
مسلما از لحاظ بهینه بودن استفاده از CTE و ROW_NUMBER و در هنگام حذف داده استفاده از DRIVED TABLE بهترین گزینه بوده و صحبت شما کاملا صحیح است.
موفق باشید

حمیدرضاصادقیان
چهارشنبه 05 آبان 1389, 22:33 عصر
سلام.روش آقای یاراحمدی پیشنهاد میشه.چون در اونجا یک بار از Clustered Index (درصورت موجود بودن) استفاده میشه و با یک join نتیجه برگردانده میشه ولی در روش آخر یک left join داریم و یک sort که خود این روی سرعت نیز تاثیر داره.
برای بهتر مشخص شدن من plan هردو رو برای شما قرار میدم.
موفق باشید