با سلام
چگونه ميتوان در sql يك فيلد ايجاد كرد كه داده هاي فيلد ديگري را به صورت تجمعي نشان دهد.
با سلام
چگونه ميتوان در sql يك فيلد ايجاد كرد كه داده هاي فيلد ديگري را به صورت تجمعي نشان دهد.
متوجه منظورتون نشدم ولی شاید منظور شما این باشه:
باید از توابع محاسبات جمعی استفاده کنین.
SELECT SUM(TEDAD*PRICE) AS PHIE FROM ORDERS
منظورم اين است كه ميخواهم فيلدي داشته باشم كه اعداد يك فيلد ديگر را جمع بزند.
مثلا در يك فيلد عدد 10 براي اولين ركورد موجو د است در فيلد مد نظر من 10 داشته باشد و براي ركورد بعدي اگر عدد50 باشد در فيلد مورد نظر من 10 را با 50 جمع كند و عدد 60 را بدهد به همين ترتيب
با view ميشه اين كار و انجام داد به نظر شما؟
سلام
من منظور شما را کامل می دانم می خواهم برای پروژه شما راه حلی ارائه دهم پس مشکل را بگوئید چون فیلد تجمعی اشتباه است و راه در لایه برنامه کاربردی دارد
این کار با یک دستور فوق العاده ساده ی Select امکان پذیر هست.
ولی در جدول باید یک ستونی وجود داشته باشه به صورت سریالی صعودی یا سریالی نزولی باشه تا عقب و جلو بودن سطرها مشخص باشه.
فرض می کنیم در جدول دو ستون به عنوان recID و Point وجود داره که به ترتیب اولی به عنوان شماره ی رکورد و دومی به عنوان مقدار دستور زیر نتیجه ی مطلوب را نمایش می دهد:
SELECT recID, Point, SumPiont = (SELECT SUM(Point)
FROM table_name AS T1
WHERE T1.recID <= T2.recID)
FROM table_name AS T2;
وبلاگ من (Advanced SQL Querying)
البته در بهترین شرایط.
مانند همونی که فرمودید، یک فیلد ردیف داشته باشیم که مقادریش به همون شکلی که میخوایم افزایش پیدا کنه و یا دستوراتی مثل RowNumber که در Sql نسخه های 2005 به بعد وجود داره.
حالا فرض رو بر این بگیرید که sql ما 2000 و فیلد مذکور رو هم نداریم. مشکلی که من دقیقا داشتم.
من برای محاسبه یک گردش حساب اشخاص حدود 4-5 تا SP و دو تا تمپ تیبل و یک کوئری نوشتم
حدود دو روز روش کار کردم و مسلما پیچیده هم شده بود. الآنم زیاد یادم نیست به چه صورت عمل میکرد ولی در کل روال کاریش اینطوری بود که به ازای هر سطر، در یکی از جداول موقت یک ردیف(autoNumber) و یک فیلد شماره ایجاد میشد که قرار بود با جدول دیگه الحاق بشه تا بشه اون کوئری شما رو اجرا کرد.
sp ها هم کارشون این بود که هر کدوم میومدن مقادیر اصلی رو از هر جدول(مثلا خرید، فروش،دریافت،پرداخت و...) با یک قالب مشخص میریختن توی جدول موقت دیگه و در نهایت همون طور که گفتم در یک sp ما این دو جدول رو جوین میکردیم و کوئری فروانی تجمعی رو بدست میاوردیم.
حاصل این کار این بود که الگوریتم شدیدا کند بود. یعنی با دو سه هزار تا رکورد requestemoon Timeout میشد!
بعد از مشورتی که با یکی از دوستان در همین سایت کردم که اول اسمش fastCode به یک نکته پی بردم و اون این بود که نیازی نیست هر کاری که با داده و کوئری گرفتن و محاسبه و ... انجام میشه رو سمت دیتابیس انجام بدیم(لقمه رو نباید پیچوند و باید ساده ترین راه رو انتخاب کرد).
روش پیشنهادی ایشون این بود که شما با union تمامی رکورد هات رو کش کن. بعد سمت application و با یک حلقه for ساده یک جمع روی فیلدی که قبلا در دستور select در نظر گرفتی بزن و حالشو ببر!
حاصل این شد که اجرای اون کوئری حدود 150 برابر سریعتر شد و به درستی و تنها با یک کوئری جواب میداد.
در ضمن مرتبه زمانی ملاک بهتریه برای محاسبه سرعت
الگوریتم اول یقینا مرتبه نمایی داشت (فرمولشو ازم نخواین)
و دومی چیزی نزدیک به (o(n!
-----------------------------------------
حالا یک سوال جانبی و اون این که آیا اطلاعات TempTable ها بر روی دیسک ذخیره میشه یا Memory؟
Temporary Table ها بطور موقت به طور فیزیکی روی دیسک ذخیره مشن. حتی Variable Table ها نیز به طور فیزیکی ذخیره میشن بر خلاف صفت "متغیر" که ما را یاد حافظه (Memory) می اندازن.حالا یک سوال جانبی و اون این که آیا اطلاعات TempTable ها بر روی دیسک ذخیره میشه یا Memory؟
وبلاگ من (Advanced SQL Querying)
سلام
اصل مسئله را نگفتید ! ببینید یک برنامه Client/Server وظایفی را برای طرفین معین میکند قرار نیست تمام حمالی گردن سرور باشد بگذارید که عملیات تجمعی سمت Client باشد درست است که با SQL هم می شود ولی Client هم باید از بار سرور کم کند و فقط با مثلا 2 گیگ رم بیکار بایستد تا سرور هلو بپر تو گلو برایش فراهم کند
با تشکر از شما Mr MSalim
-----------
به نظر من چرا.
در حالت عادی توی برنامه های تحت وب که هست(وب سایت ها).
تو برنامه های اپلیکیشنی و خصوصا تحت شبکه وقتی که برنامه به صورت لایه ای باشد و از لایه Business logic به پایین روی یک سرور قرار داشته باشد خواهید دید که این اتفاق میفتد(باید بیفتید). یعنی تمامی عملیات روی یک سرور اتفاق میفتد و تنها عملیات مرور داده ها و دریافت فرم ها در سمت کلاینت انجام میشود.
در این حالت یک محاسبه تجمعی در لایه منطق و یا دسترسی به داده انجام میشه که لزوما نباید با Sql انجام بشه و میشه با همون حلقه هم که گفتم محاسبه رو انجام داد و به لایه بالایی فرستاد.
سلام
یک Web Server داریم و یک DataBase Server و SQLServer عمدتا روی DataBase Server است فرض کنیم از معماری دات نت استفاده کنیم اینطوری واکشی داده ها در یک DataSet یا DataTable اتفاق می افتد در هر صورت این DT در سمت Client است یا روی Web Server نه روی DataBase Server منظورم اینستکه در Win بین Client و DataBase Server است و در Web بین Web Server و DataBase Server پس می بینید که حمالی بخشی از گردن DataBase Server باز شده است مگر اینکه کسی Web Server و DataBase Server را یکی کند! (امنیت داده ها / ....)
سلام،
درسته اون روش ممکنه در مجموعه داده های زیاد مشکل عملکردی داشته باشه. پس روش زیر را معرفی می کنم که دوبار بیشتر جدول Scan نمیشه:
declare @t table (recID int identity, point int)
insert @t select 10 union select 25 union select 60
--Bad solution
SELECT recID, Point, SumPiont = (SELECT SUM(Point)
FROM @t AS T1
WHERE T1.recID <= T2.recID)
FROM @t AS T2;
--Good Solution
SELECT T1.recID, T1.point, SUM(T2.point) AS Sumpoint
FROM @t AS T1
INNER JOIN @t T2
ON T1.recID >= T2.recID
GROUP BY T1.recID, T1.point
وبلاگ من (Advanced SQL Querying)
سلام
راستش نمی تونم این کوئری را تجسم کنم به نظرم فرقی نکرده نگاه کن Execution Plan چی نشون میده شایدم !
حق با شماست این روش اصلا کارامد نیست. و مشکل عملکردی عجیبی داره.
ظاهرا روشهای خیلی بهتره وجود داره که از این مقاله میشه خواند:
http://www.sqlservercentral.com/articles/T-SQL/68467/
وقتی مقاله فوق را دیدم یکم از خودم دلسرد شدم. شاید نیاز باشه یک مدت برم کمی دوپینگ کنم و دوباره به Forum برگردم
بعد از پایان این ماه میخوام برم T-SQL و SQL Server کمی یاد بگیرم. و اگر خدا خواست دوباره به این سایت برگردم.
الان تنها هدفهم اینه که 300 پست در این ماه بزنم.
وبلاگ من (Advanced SQL Querying)
سلام
آقا محمد عزیز زحمات شما جای بسی تشکر دارد در پروژه های کاربردی برنامه نویسان این قسمت را عموما در سمت برنامه کاربردی فقط با چند خط انجام میدهند وشاید نیازی نباشد که این قسمت توسط TSQL انجام شود.
یعنی ما برنامه نویس نیستیم دیگهدر پروژه های کاربردی برنامه نویسان این قسمت را
به شخصا علاقه دارم هرچیزی که با داده ها مرتبط است را در سمت Server پیاده کنم، بالاخره یک روشی پیدا میشه که Efficient باشه اونم از نوع set-based اش
وبلاگ من (Advanced SQL Querying)
سلام
اختیار دارید آقا محمد عزیز شما استاد هستید منظورم افرادی که برنامه نویسی کاربردی میکنند
من نميدونم منظورت رو درست فهميدم يا نه. اگه ميخواي روي يك سطر جمع مقادير سطر يا سطرهايي كه در گذشته (ركوردهاي قبل) ثبت شدن رو محاسبه كني (مثل مانده يك حساب در گردش آن توي برنامه حسابداري يا موجودي كالا در هر روز در برنامه انبار) بهتره يه سري به دستور with كه از نسخه 2005 به بعد اضافه شده بزني. اين دستور بهت اجازه ميده select رو بصورت بازگشتي تعريف كني. يعني هر سطر از داده رو اونقدر فراخواني بكنه و به ازاي اين فراخواني ها محاسبه بكنه تا به ركورد اولت برسه. نيازي به تعريف select توو در توو هم نباشه. اگه از توضيحات من چيزي نفهميدي يه سري به help بزن.