PDA

View Full Version : جستجو اعداد



damanpak
جمعه 15 اردیبهشت 1391, 16:11 عصر
سلام به اساتید گرانقدر
از اساتید بزرگوار میخواستم بپرسم که آیا کدی هست که با توجه به رنجی از اعداد که فیلد میتواند بپذیرد عددی که در آن ثبت نشده است را نشان بدهد؟
مثلا توی یه جدول فیلد کد اصلی از نوع INT میباشد و دارای محتویات 1,2,3,4,5,6,8,9
حالا میخوام عدد 7 که در این فیلد ذخیره نشده است رو نشون بده
دقت کنید که نمیخوام از سرچ استفاده کنم چون داده ها خیلی زیاد هستند
میخوام از دستورات خود اس کیو ال استفاده کنم
مثل دستور select avg(field)from table

hamid_kz
شنبه 16 اردیبهشت 1391, 10:54 صبح
من اينجوري به ذهنم رسيد كه سريعتره.. البته گفتيد INT، اگر نوع ديتا بزرگتر باشه ميتونيد تغييرش بديد..

DECLARE @D AS INT = 0
DECLARE @I AS INT = 1
DECLARE @Q AS VARCHAR(MAX) = ''
SELECT @D = MAX([فيلد عددي]) FROM [جدول]
WHILE @I<=@D
BEGIN
SET @Q = @Q + 'SELECT ID = ' + CAST(@I AS VARCHAR(5)) + ' UNION ALL '
SET @I = @I + 1
END
SET @Q = LEFT(@Q, LEN(@Q) - 10)
SET @Q = 'SELECT * FROM (' + @Q + ')A WHERE ID NOT IN (SELECT [فيلد عددي] FROM [نام جدول])'
EXEC(@Q)

damanpak
شنبه 16 اردیبهشت 1391, 11:13 صبح
من اينجوري به ذهنم رسيد كه سريعتره.. البته گفتيد INT، اگر نوع ديتا بزرگتر باشه ميتونيد تغييرش بديد..

DECLARE @D AS INT = 0
DECLARE @I AS INT = 1....

ممنون از پاسخ شما اما جواب سوالم رو نتونست بده آخه خیلی خطا میگیره توی اس کیو الم
اگه میشه لطف کنید همین سورس رو روی یه دیتابیس اس کیو ال پیاده کنید و بانک رو هم اینجا قرار بدین تا بیبنم شاید من دستورات رو اشتباه میدم بهش یا اینکه این اطلاعات رو توی سورسی که گذاشتین قرار بدین لطفا
نام جدول ranandeh
نام فیلد ids که از نوع int
نام دیتابیس هم اگه نیاز بود modiryat

hamid_kz
شنبه 16 اردیبهشت 1391, 13:42 عصر
چه خطايي ميده؟؟؟ نبايد خطا بده.. هم منطقش رو چك كردم .. هم روي ديتابيس هاي ديگه.. 2008 داريد ديگه؟؟

mohsen.net
شنبه 16 اردیبهشت 1391, 14:05 عصر
من اينجوري به ذهنم رسيد كه سريعتره.. البته گفتيد INT، اگر نوع ديتا بزرگتر باشه ميتونيد تغييرش بديد..

DECLARE @D AS INT = 0
DECLARE @I AS INT = 1
DECLARE @Q AS VARCHAR(MAX) = ''
SELECT @D = MAX([فيلد عددي]) FROM [جدول]
WHILE @I<=@D
BEGIN
SET @Q = @Q + 'SELECT ID = ' + CAST(@I AS VARCHAR(5)) + ' UNION ALL '
SET @I = @I + 1
END
SET @Q = LEFT(@Q, LEN(@Q) - 10)
SET @Q = 'SELECT * FROM (' + @Q + ')A WHERE ID NOT IN (SELECT [فيلد عددي] FROM [نام جدول])'
EXEC(@Q)



فکر نکنم این راه خوبی باشه
فرض کنید یک جدول به نام test دارید که یک ستون یه نام col1 از نوع عددی دارید



SELECT col1+1 FROM Test t1
WHERE NOT Exists(SELECT * FROM Test t2 WHERE t1.col1+1=t2.col1)

hamid_kz
شنبه 16 اردیبهشت 1391, 14:13 عصر
حداقل روي ديتاي خود من جواب نداد.. من يك جدول دارم كه مقادير يكي از فيلدهاي آن از 2 شروع ميشود تا 10. اين اسكريپت مقدار 11 را برمي گرداند.. در حالي كه بايد مقدار يك را برگرداند.

hamid_kz
شنبه 16 اردیبهشت 1391, 14:17 عصر
نمونه زير را هم مي توانيد ببينيد:

SELECT * INTO #TempTest FROM (SELECT Id = 2 UNION SELECT 5 UNION SELECT 7 UNION SELECT 11 UNION SELECT 15)A
SELECT Id+1 FROM #TempTest t1
WHERE NOT Exists(SELECT * FROM #TempTest t2 WHERE t1.Id+1=t2.Id)

كه خروجي صحيح نيست

damanpak
شنبه 16 اردیبهشت 1391, 14:35 عصر
سلام به اساتید گرانقدر
از اساتید بزرگوار میخواستم بپرسم که آیا کدی هست که با توجه به رنجی از اعداد که فیلد میتواند بپذیرد عددی که در آن ثبت نشده است را نشان بدهد؟
مثلا توی یه جدول فیلد کد اصلی از نوع INT میباشد و دارای محتویات 1,2,3,4,5,6,8,9
حالا میخوام عدد 7 که در این فیلد ذخیره نشده است رو نشون بده
دقت کنید که نمیخوام از سرچ استفاده کنم چون داده ها خیلی زیاد هستند
میخوام از دستورات خود اس کیو ال استفاده کنم
مثل دستور select avg(field)from table


سلام دوباره من کد بالا رو با استفاده از روش جستجو پیدا کردم(که مایل به استفاده از این روش نبودم و امیدوار بودم دستور بهتری پیداکنم:ناراحت::ناراحت:)و در این پست قرار میدم تا شاید کمکی بشه به اساتید برنامه نویس در پیدا کردن کد غیر تکراری.

کد زیر رو در قالب یک روال(Function)ذخیره کردم به این صورت
create function rndids(@ntbl nchar(35),@nfld nchar(35))
returns int
as
BEGIN
declare @idme int
set @idme=1
while @idme=any(select ids from ranandeh)
begin
set @idme=@idme+1
end
return @idme

END -- fn def

حال بااستفاده از دستور select distinct(dbo.rndids('ranandeh','ids')) from ranandeh نام جدول و نام فیلدی که میخوام کد غیر تکراری براش پیدا کنم رو به عنوان پارامتر میفرستم تا کد مورد نظر تولید بشه؛فقط تنها مشکل اینه که به تعداد رکوردهای ذخیره شده در جدولی که نامش به عنوان پارامتر روال فرستاده میشه عدد غیر تکراری رو نشون میده که با عبارت distinct این مشکل رفع شده از دوستان خواهشمنده اگه راهی مد نظر دارن بگن تا بدون استفاده از عبارت distinct فقط یک فیلد رو برگردونه

باتشکر دامن پاک

hamid_kz
شنبه 16 اردیبهشت 1391, 14:39 عصر
خب من هم كد بالا رو براي شما نوشتم ديگه.. يه SP با كد بالا كارتونو راه ميندازه..

damanpak
شنبه 16 اردیبهشت 1391, 14:59 عصر
سلام دوباره من کد بالا رو با استفاده از روش جستجو پیدا کردم(که مایل به استفاده از این روش نبودم و امیدوار بودم دستور بهتری پیداکنم:ناراحت::ناراحت:)و در این پست قرار میدم تا شاید کمکی بشه به اساتید برنامه نویس در پیدا کردن کد غیر تکراری.

کد زیر رو در قالب یک روال(Function)ذخیره کردم به این صورت
create function rndids(@ntbl nchar(35),@nfld nchar(35))
returns int
as
BEGIN
declare @idme int
set @idme=1
while @idme=any(select ids from ranandeh)
begin
set @idme=@idme+1
end
return @idme

END -- fn def
باتشکر دامن پاک

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

create function rndids(@ntbl nchar(35),@nfld nchar(35))
returns int
as
BEGIN
declare @idme int
set @idme=1
while @idme=any(select @nfld from @ntbl)
begin
set @idme=@idme+1
end
return @idme
END -- fn def

اما نمیدونم چرا میگه @ntbl رو نمیشناسه باوجود اینکه اینجا create function rndids(@ntbl nchar(35),@nfld nchar(35)) تعریفش کردم:گریه::گریه::گریه:

mohsen.net
شنبه 16 اردیبهشت 1391, 16:05 عصر
راه بهتر استفاده از یک جدول Auxiliary است
فرض کنید حداکثر تعداد رکورد های موجود 10000 است
ابتدا یک جدول با اعداد از 1 تا 10000 می سازیم ، که با کویری زیر زمان خیلی کمی می بره
بعد با یک Select ساده می بینیم کدام اعداد در جدول کمکی وجود ندارند
حالش را ببرید


DECLARE @max AS INT, @rc AS INT;
SET @max = 10000;
SET @rc = 1;
CREATE TABLE #Nums(n INT);

INSERT INTO #Nums VALUES(1);
WHILE @rc * 2 <= @max
BEGIN
INSERT INTO #Nums SELECT n + @rc FROM #Nums;
SET @rc = @rc * 2;
END
INSERT INTO #Nums
SELECT n + @rc FROM #Nums WHERE n + @rc <= @max;

----------------------------------------------
SELECT * INTO #TempTest FROM (SELECT ID = 2 UNION SELECT 5 UNION SELECT 7 UNION SELECT 11 UNION SELECT 15)A

SELECT n FROM #Nums WHERE n NOT IN(SELECT ID FROM #TempTest)
AND n BETWEEN (SELECT MIN(ID) FROM #TempTest) AND (SELECT MAX(ID) FROM #TempTest)
DROP TABLE #TempTest
DROP TABLE #Nums

mohsen.net
شنبه 16 اردیبهشت 1391, 16:07 عصر
این هم خروجی


n
3
4
6
8
9
10
12
13
14

damanpak
شنبه 16 اردیبهشت 1391, 23:23 عصر
این هم خروجی


n
3
4
6
8
9
10
12
13
14
ممنون از شما دوست خوبم به خاطر زحماتی که کشیدین اما من ترجیح میدم که از کد قبلیتون استفاده کنم که جواب درستی داره و فقط یه لطفی بکنید بگین که انشاالله این کد تحت هیچ شرایط جواب اشتباه نمیده و خیالم راحت باشه؟
کد شما:
SELECT col1+1 FROM Test t1 WHERE NOT Exists(SELECT * FROM Test t2 WHERE t1.col1+1=t2.col1)

فقط من یک عبارت top 1 بهش اضافه کردم که جواب سوالمو گرفتم

بازم ممنون از زحمات شما

mohsen.net
یک شنبه 17 اردیبهشت 1391, 08:45 صبح
کد قبلی در حالتی که اعداد از دست رفته بیشتر از 2تا باشه کار نمی کنه مثل توالی 1و2و3و7و9
اما کد دوم در هر حالتی کار می کنه و زمان بسیار خوبی هم داره
در ضمن جدول Nums را می توانی به جای temptable به صورت یک جدول واقعی در نظر بگیری و فقط یک بار بسازیش و بقیه موارد ازش استفاده کنید

damanpak
یک شنبه 17 اردیبهشت 1391, 09:36 صبح
کد قبلی در حالتی که اعداد از دست رفته بیشتر از 2تا باشه کار نمی کنه مثل توالی 1و2و3و7و9
اما کد دوم در هر حالتی کار می کنه و زمان بسیار خوبی هم داره
در ضمن جدول Nums را می توانی به جای temptable به صورت یک جدول واقعی در نظر بگیری و فقط یک بار بسازیش و بقیه موارد ازش استفاده کنید
آره درسته حرفتون که در مواردی که تعداد بیشتری عدد باشه کار نمیکنه
خب پس اگه میشه لطف کنید کد زیر رو توضیح بدین که روش عملکردش چطوریه و این خروجی هایی که داده از کجا آورده



DECLARE @max AS INT, @rc AS INT;
SET @max = 10000;
SET @rc = 1;
CREATE TABLE #Nums(n INT);

INSERT INTO #Nums VALUES(1);
WHILE @rc * 2 <= @max
BEGIN
INSERT INTO #Nums SELECT n + @rc FROM #Nums;
SET @rc = @rc * 2;
END
INSERT INTO #Nums
SELECT n + @rc FROM #Nums WHERE n + @rc <= @max;

----------------------------------------------
SELECT * INTO #TempTest FROM (SELECT ID = 2 UNION SELECT 5 UNION SELECT 7 UNION SELECT 11 UNION SELECT 15)A

SELECT n FROM #Nums WHERE n NOT IN(SELECT ID FROM #TempTest)
AND n BETWEEN (SELECT MIN(ID) FROM #TempTest) AND (SELECT MAX(ID) FROM #TempTest)
DROP TABLE #TempTest
DROP TABLE #Nums

mohsen.net
یک شنبه 17 اردیبهشت 1391, 11:25 صبح
تا قبل از خط توضیحات کل کاری که می کنیم یک جدول می سازیم با یک ستون که مقادیرش از 1 هستند تا 10000
بعد جدول هدف را می سازیم با توالی اعداد 2و5و7و11و15


SELECT n FROM #Nums WHERE n NOT IN(SELECT ID FROM #TempTest)
AND n BETWEEN (SELECT MIN(ID) FROM #TempTest) AND (SELECT MAX(ID) FROM #TempTest)
هم از جدول اعداد (Nums) اعدادی را انتخاب می کند که در جدول هدف نیستند و در محدوده اعداد این جدول هستند

damanpak
یک شنبه 17 اردیبهشت 1391, 14:10 عصر
تا قبل از خط توضیحات کل کاری که می کنیم یک جدول می سازیم با یک ستون که مقادیرش از 1 هستند تا 10000
بعد جدول هدف را می سازیم با توالی اعداد 2و5و7و11و15


SELECT n FROM #Nums WHERE n NOT IN(SELECT ID FROM #TempTest)
AND n BETWEEN (SELECT MIN(ID) FROM #TempTest) AND (SELECT MAX(ID) FROM #TempTest)
هم از جدول اعداد (Nums) اعدادی را انتخاب می کند که در جدول هدف نیستند و در محدوده اعداد این جدول هستند

دوست عزیز گفتین که :تا قبل از خط توضیحات کل کاری که می کنیم یک جدول می سازیم با یک ستون که مقادیرش از 1 هستند تا 10000
اما از رکورد 4558 به بعد اعدادی که ذخیره کرده درست نیست یعنی باید بعدش 4559 بیاد اما 4565 اومده؛در کل از رکورد 4558 به بعد اعدادی که ذخیره کرده درست نیست

در کل هدف من از ایجاد این تایپیک ساخت قطعه سورسی هستش که توی جدولی که میخوام اطلاعات ذخیره کنم کلید اصلی رو تولید کنه و میخوام که هرکدوم از رکوردها به وسیله کاربر پاک شد کلید همون فیلد رو برای درج رکورد جدید در نظر بگیره تا تمام اعدد از 1 تا بالاترین کلید اصلی تولید شده در جدول ذخیره بشه