ورود

View Full Version : کمک در مورد نوشتن یک sp



mohsen_zelzela00
شنبه 23 دی 1391, 18:34 عصر
با عرض سلام خدمت اساتید محترم
من یک جدول دارم با ساختار زیر

CREATE TABLE [dbo].[Report4](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Mesc] [nvarchar](50) NOT NULL,
[Line] [char](1) NOT NULL,
[Unit] [varchar](4) NOT NULL,
[Description] [varchar](200) NOT NULL,
[ST_CODE] [char](1) NULL,
[PbsNo] [varchar](20) NULL,
[PbsDate] [varchar](10) NULL,
[PbsQty] [int] NULL,
[PbsQtyRec] [bigint] NULL,
[QtyConsum1] [int] NULL,
[QtyConsum2] [int] NULL,
[QtyConsum3] [int] NULL,
[QtyConsum4] [int] NULL,
[QtyConsum5] [int] NULL,
[Type] [nvarchar](20) NULL,
[InvQty] [int] NOT NULL,
[TypeRequest] [int] NOT NULL,
[HeaderId] [bigint] NOT NULL,
[LOCATION] [varchar](50) NULL,
CONSTRAINT [PK_Report4] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO


که داده های این جدول نزدیک به 2000000 رکورد است و من می خواهم یک Query بنویسم منطق زیر را ایجاد کنم.(من یک مثال از این جدول را اینجا (http://188.40.250.235:888/MyMat.rar)قرار دادم)

در این جدول یک سری رکورد وجود دارد با Line='H' , Line='I'.
که در اینجا منظور از h هدر است و منظور از I ، آیتم های هدر می باشند(این یک سیستم کالا است ابتدا با استفاده از هدر مشخصات کالا را بیان می کند و I مشخصات آیتم ها را مشخص می کند)
در این جدول برای اینکه هدرها را آیتم ها را مشخص کنم یک فیلد با عنوان HeaderId قرار دادم که مشخص می کنیم که این آیتم ها متعلق به کدام هدر هستند
98308

در عکس بالا اگر به رکورد 11 دقت کنید مقدار فیلد HeaderId برابر 134228000. این بدین معنا است که هدر این ایتم کد 134228000 (منظور از کد فیلد Mesc است)
حال می خواهم زمانی که داد ها را به کاربر نشان دهم داده ها جوری پشت سر هم قرار گیرند که ابتدا هدر های آیتم ها وبعد از آن خود آیتم ها قرار گیرند مانند عکس زیر

98308

و این sp باید قابلیت این رو داشته باشه که به صورت داینامیک باشه(چون کاری که الان من دارم انجام میدم یه جوری گزارشگیری است) یعنی اینکه من بتونم یک شرط برای این SP خودم بفرستم مثلاً اگر من این شرط را به این Sp ارسال کردم(این نمونه است می تونه هر شرط دیگری هم باشد)

Description like'% pump%'




زمانی که این شرط را بخواهم اعمال کنم باید شرایط زیر را در نظر بگیرد
1. ممکن است که کلمه pump در رکوردهای با Line=H باشد
در این صورت هدرها و تمام آیتم های آن هدر را باید لیست کند

2. ممکن است که کلمه pump در رکوردهای با Line=I باشد
در این صورت آن آیتم و تمام هدرهای آن آیتم را باید لیست کند مانند زیر

98310

اگر به سطر 7 دقت کنیم ایتم های با هدرهایی را لیست می کند که هر دو شرط بالا را داشته باشندو

ممنون میشم اساتید محترم راهنمایی کنند

محمد سلیم آبادی
شنبه 23 دی 1391, 21:49 عصر
سلام،
بنظرمیرسه جدولتون کاملا غیرنرمال هست. شما ابتدا باید جدول رو به شکل نرمال دربیارین سپس سعی کنید گزارش گیری کنید.

mohsen_zelzela00
شنبه 23 دی 1391, 22:01 عصر
سلام،
بنظرمیرسه جدولتون کاملا غیرنرمال هست. شما ابتدا باید جدول رو به شکل نرمال دربیارین سپس سعی کنید گزارش گیری کنید.
استاد میشه مشکلش رو بگید یا اینکه بگید دقیقاً چه کار کنم تا اونو تبدیل به یک جدول نرمال کنم؟ من در تمام پروژه هام نرمال سازی رو رعایت می کنم ولی این پروژه سه ماهی هست که خواب و خوراک رو از من گرفته چون Query های آن خیلی پیچیده با داد های خیلی زیاد است که قراره نرم افزاری که طراحی کنم تحت وب باشه که این باعث میشه که سرعت لود خیلی پایین بیات و کاربر کلافه بشه. ممنون میشم اگه براتون مقدور باشه راهنمایی کنید.

محمد سلیم آبادی
شنبه 23 دی 1391, 22:23 عصر
من در تمام پروژه هام نرمال سازی رو رعایت می کنمرعایت میکنید جدول به این شکل در اومده وای به حال اون موقعی که رعایت نشه:ناراحت:
قبل از هر چیزی لطفا در کدی که در پست اولتون هست تمام سطرهای مربوط به CREATE NONCLUSTERED INDEX (یعنی کدهای مربوط به ساخت ایندکسها) را حذف کنید تا فضای کمتری اشغال بشه.
سپس بجای صحبت درمورد گزارش مورد نظر راجب داده های موجود در جداول صحبت کنید. یکایک ستونهاتون رو شرح بدین و بگین سعی دارین درمورد چه موجودیتی اطلاعات ذخیره کنید.

چرا سطرهایی با مقدار Line برابر با l را داخل یک جدول و سطرهایی با مقدار Line برابر با H را در جدول دیگر ذخیره نکردین؟ یعنی باید این جدول split بشه به دو جدول.
آیا کلید خارجی رو در صورت نیاز در جدول لحاظ کردین؟
چرا جدول هیچ قیدی نداره؟
چرا روی انتخاب data type ها اصلا دقت نشده؟ آیا تمام ستون های Qty مقادیر به خود میگیرین؟ اگه بله چرا از نوع عددی نیست؟
چرا ستون Line دارای Data Type از نوع varchar به طول 5 هست در صورتی که فقط دارای یکی از دو مقدار 'H' و 'L' هست؟ نباید char به طول 1 میگرفتین و قید میگذاشتین که دارای یکی از دو مقدار مذکور باشه؟
چرا تمام ستون ها Null-able هستند؟

mohsen_zelzela00
شنبه 23 دی 1391, 23:12 عصر
قبل از هر چیزی لطفا در کدی که در پست اولتون هست تمام سطرهای مربوط به CREATE NONCLUSTERED INDEX (یعنی کدهای مربوط به ساخت ایندکسها) را حذف کنید تا فضای کمتری اشغال بشه.


در پست اول انواع داده ها و NULLABLE را اصلاح کردم




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



Mesc : کد کالا در این فیلد ذخیره می شود که همیشه یک عدد10-11 رقمی است
Line: در اینجا مشخص می شود که این رکورد I است یا H
Unit: واحد این رکورد است که برای رکوردهای یا Line=H مقادیر عددی 01،02،03....25و برای آیتم ها مقادیری مثل NO،STو... را بگیرد
Description: توضیح در مورد کالا است
ST_CODE: یک رمز است که فقط برای آیتم ها است و مقادیری که می تونه بگیره c،x،Qو...
PbsNo:شماره سفارش است کالا است که عددی نمی باشد (مثلاً PBS-11301-S) که ممکن است بعضی از آیتم ها شماره سفارش نداشته باشند
PbsDate: تاریخ سفارش است که برای آیتم های که شماره سفارش دارند تاریخ شفارش اونها در اینجا ثبت می شود.
PbsQty: تعداد سفارش است
PbsQtyRec: تعداد رسیده از سفارش است.
QtyConsum1: تعداد مضرف در دوره اول
QtyConsum2:تعداد مضرف در دوره دوم
QtyConsum3:تعداد مضرف در دوره سوم
QtyConsum4:تعداد مضرف در دوره چهارم
QtyConsum5:تعداد مضرف در دوره پنچم
InvQty: تعداد مصرفی کالا را مشخص می کند
TypeRequest: نوع درخواست را مشخص می کند که مقادیر 1،2،3 را می تونه بگیره
HeaderId: کد هدر رو مشخص می کند
LOCATION: محل نگه داری کالا را مشخص می کند برای محصولاتی که موجودی ندارند این فیلد NULL است




چرا سطرهایی با مقدار Line برابر با l را داخل یک جدول و سطرهایی با مقدار Line برابر با H را در جدول دیگر ذخیره نکردین؟ یعنی باید این جدول split بشه به دو جدول.
آیا کلید خارجی رو در صورت نیاز در جدول لحاظ کردین؟
چرا جدول هیچ قیدی نداره؟
چرا روی انتخاب data type ها اصلا دقت نشده؟ آیا تمام ستون های Qty مقادیر به خود میگیرین؟ اگه بله چرا از نوع عددی نیست؟
چرا ستون Line دارای Data Type از نوع varchar به طول 5 هست در صورتی که فقط دارای یکی از دو مقدار 'H' و 'L' هست؟ نباید char به طول 1 میگرفتین و قید میگذاشتین که دارای یکی از دو مقدار مذکور باشه؟
چرا تمام ستون ها Null-able هستند؟



استاد این داده ها متعلق به سیستم من نیست و من دارم اوینها رو از یک سیستم مین فریم به صورت یک فایل TEXT واکشی می کنم و به این قالب در می یارم و یه چیزی حدوده 50 گزارش رو از این فایل ایجاد می کنم اگر بخواهم که هدرها و ایتم ها رو در دو جدول جداگانه لحاظ بکنم باید به ازای هر گزارش دو جدول ایجاد کنم من برای همین گفتم که با یه فیلد I وH اینها رو جدا کنم.
در این جدول ها کلید خارجی وجود ندارد.
در مورد نوع داده در پست اول اصلاح کردم.

محمد سلیم آبادی
شنبه 23 دی 1391, 23:34 عصر
قرار بر این بود که راجب خود جدول صحبت کنید. بگید که اصلا این جدول چیه و مربوط میشه به چه چیزهایی...


در این جدول برای اینکه هدرها را آیتم ها را مشخص کنم یک فیلد با عنوان HeaderId قرار دادم که مشخص می کنیم که این آیتم ها متعلق به کدام هدر هستند
سطری که از نوع Header هست بازم دارای مقداری در ستون HeaderID هست چرا؟ شما میگین HeaderID مربوط هست فقط برای آیتم ها نه برای Header ها.


در پست اول انواع داده ها و NULLABLE را اصلاح کردم
پست اولتون ویرایش نشده که.


این داده ها متعلق به سیستم من نیست و من دارم اوینها رو از یک سیستم مین فریم به صورت یک فایل TEXT واکشی می کنم و به این قالب در می یارم
اینو از اول میگفتین. مشکل همین جاست. واقعیتش من نمیتونم روی اینگونه جداول گزارشگیری کنم.


اگر بخواهم که هدرها و ایتم ها رو در دو جدول جداگانه لحاظ بکنم باید به ازای هر گزارش دو جدول ایجاد کنم من برای همین گفتم که با یه فیلد I وH اینها رو جدا کنم.
منظورتون رو متوجه نمیشم. شما دو جدول دارین حالا n تا گزارش بر اساس این دو جدول انجام میدین.

محمد سلیم آبادی
شنبه 23 دی 1391, 23:47 عصر
حال می خواهم زمانی که داد ها را به کاربر نشان دهم داده ها جوری پشت سر هم قرار گیرند که ابتدا هدر های آیتم ها وبعد از آن خود آیتم ها قرار گیرند
سوال: این داده ها با این فرمت چه به درد کاربر میخوردند که شما میخواهین به شکل مرتب شده (ابتدا Header ها و سپس Item های اونها) نمایش بدین؟

برای اینکه ابتدا Header و سپس Item های اون نمایش داده بشه میتونید بنویسید:
ORDER BY HeaderID, Line

mohsen_zelzela00
یک شنبه 24 دی 1391, 00:02 صبح
قرار بر این بود که راجب خود جدول صحبت کنید. بگید که اصلا این جدول چیه و مربوط میشه به چه چیزهایی...


سطری که از نوع Header هست بازم دارای مقداری در ستون HeaderID هست چرا؟ شما میگین HeaderID مربوط هست فقط برای آیتم ها نه برای Header ها.


پست اولتون ویرایش نشده که.


اینو از اول میگفتین. مشکل همین جاست. واقعیتش من نمیتونم روی اینگونه جداول گزارشگیری کنم.


منظورتون رو متوجه نمیشم. شما دو جدول دارین حالا n تا گزارش بر اساس این دو جدول انجام میدین.

بله در ستون HeaderId دقیقاً من اومدم برای هدرها همون کد هدر رو گزاشتم گفتم که شاید برای Query نویسی مفید باشه.

استاد در حقیقت جداول DataBase اصلی به صورت زیر است
INV: که موجودی فعلی کالا را نگه داری می کند
LIB: که مشخصات نمام کالا در آن است
OUT: که مشخصات تمام خروجی های کالا در آن ثبت می شود
TRAN: که تمام ترزاکشن های مربوط به کالا در آن ذخیره می شود

حال من باید با توجه یه این جداول یک سری گزارش ایجاد می کردم و با توجه به اینکه داد های درون این جداول شبیه به بازار شام است من اومدم به ازای هر گزارش یک جدول ایجاد کردم که ابتدا سری اول مثلاً اول هفته زمانی که فایل Text را درون وب سایت Import کردن من ابتدا بیام تمام داده های جدول گزارش 2 رو پاک کنم و با توجه به منطق گزارش 2 دادد های آن را واکشی کنم و درون جدول دو Insert کنم و برای بقیه گزارشات دقیقاً همین روند رو انجام میدم.
حال که تمام داد های گزازشات درون جدول خاص خودشون قرار گرفتند کاربر زمانی که بخواهد مثلاً موجودی صفر کالا را بگیرد کاری به جداول اصلی ندارد بلکه مستقبم از جدول Report2 دادها رو واکشی می کند و به کاربر نشان می دهد این دقیقاً منطق کار این سیستم است.

در حقیقت در جدول Report4 روند مصرف اقلام قرار می گیرد یعنی اینکه یک کد کالا را مشخص می کند و می گوید در سه ماه جاری چقدر مصرف داشته ، در دوره اول چقدر مصرف داشته و ....(من تمام فرمول ها را اعمال کردم ودر اینحا اطلاعات آماده هستند که فقط به کاربر نمایش داده شوند).

ممنون میشم باز هم من رو راهنمایی کنید.

mohsen_zelzela00
یک شنبه 24 دی 1391, 00:10 صبح
سوال: این داده ها با این فرمت چه به درد کاربر میخوردند که شما میخواهین به شکل مرتب شده (ابتدا Header ها و سپس Item های اونها) نمایش بدین؟




اره این اطلاعات باید واقعاً به این صورت نمایش داده شوند چون درون لاین های Header یه توضیحی در مورد آیتم های کالا ذکر شده منجمله که ساخت کدام کشور است کدام شرکت اونها رو تامینن کرده و کلی اطلاعات دیگر . برای همین باید دقیقاً پشت سر هم قرار بگیرند. من یک Query برای این کار نوشتم (http://barnamenevis.org/showthread.php?375550-%D8%B7%D9%88%D9%84-%DA%A9%D8%B4%DB%8C%D8%AF%D9%86-%D8%B2%D9%85%D8%A7%D9%86-%D8%A7%D8%AC%D8%B1%D8%A7%DB%8C-Query) و شما هم لطف کردید و یه مقدار Query من رو اصلاح کردید ولی خب کامل بهم جواب نمی دهد و چون عنوان پستم یه چیز دیگه بود گفتم که یه تاپیک دیگر ایجاد کنم

محمد سلیم آبادی
یک شنبه 24 دی 1391, 10:51 صبح
مشکلتون فقط همین مرتب کردن هست دیگه درسته؟
لطف میکنید یکبار دیگه مشکلتون رو مطرح کنید(همونی که در پست اول مطرح شده) اینبار خیلی ساده تر، فقط تو تصاویر ستونهایی باشن که ضرورت دارن (نه همه) مثلا Mesc و HeaderIDو Description و اینجور ستونها.
و همچنین قسمت دوم مشکلتون که راجب داینامیک بودن صحبت شده یکمی مساله رو بهتر مطرح کنید.

دستور زیر جدول رو به ترتیب مورد نظر نشون میده. فقط قسمت دوم مساله رو من نفهمیدم.

ORDER BY HeaderID, Line

mohsen_zelzela00
یک شنبه 24 دی 1391, 21:21 عصر
مشکلتون فقط همین مرتب کردن هست دیگه درسته؟
لطف میکنید یکبار دیگه مشکلتون رو مطرح کنید(همونی که در پست اول مطرح شده) اینبار خیلی ساده تر، فقط تو تصاویر ستونهایی باشن که ضرورت دارن (نه همه) مثلا Mesc و HeaderIDو Description و اینجور ستونها.
و همچنین قسمت دوم مشکلتون که راجب داینامیک بودن صحبت شده یکمی مساله رو بهتر مطرح کنید.

دستور زیر جدول رو به ترتیب مورد نظر نشون میده. فقط قسمت دوم مساله رو من نفهمیدم.

ORDER BY HeaderID, Line

بله بیشتر مرتب کردن است و اینکه قسمت داینامیک را درست نمایش دهد.
من زمانی که داده ها را با استفاده از کنترل JQGrid به کاربر نشون دادم می خواهم قابلیت جستجو را نیز فعال کنم که کاربر بتونه در داده هایی که بهش نشون داده میشه عمل جستجو را انجام بده(من با خود کنترل JQGrid هیچ مشکلی ندارم و مشکل من با Query است).
برای اینکه بتونم راحت تر منظور خودم را برسونم اجازه بدید با یه مثال این کار رو انجام بدم.
من در سری اولی که صفحه لود میشه می یام 100 رکورد اول رو واکشی می کنم و به کاربر نشون میدم(رکوردها نمایش داده شده باید از قانون هدر و آیتم تبعیت کنن)
98360
حال بعد از نمایش این لیست کاربر می خواهد رکوردهایی را ببیند که در فیلد شرح کالای آن کلمه PUMP آمده باشد. برای این کار بر روی علامت زربین پایین صفحه کلیک می کند تا فرم جستجو مربوط ظاهر شود و کاربر مطابق زیر فرم را پر می کند.
98361


حال با توجه به این کار من پارامتر زیر را سمت SP مورد نظر ارسال می کنم

(Description LIKE '%pump%')',1,100


حال با توجه به این پارامترها 1 به معنی صفحه اول است و 100 به معنی اینکه در هر صفحه 100 رکورد وجود دارد نوبت به شرح کالا می رسد که می گوید شرح کالا باید حاوی PUMP باشد. برای این مورد می توان دو حالت در نظر گرفت.

حالت اول: ممکن است که کلمه PUMP در شرح کالای رکورد هدر باشد(line=H): در این حالت هدر و تمام آیتم های آن هدر انتخاب می شوند

حالت دوم: ممکن است که کلمه PUMP در شرح کالای آیتم ها باشد: در این صورت آن آیتمی که شرح کالای آن حاوی PUMP است + هدر آن انتخاب می شود.

اگه بخوام ساده تر بگم می تونم بگم که در جستجو هم باید هدرهای هر آیتم بالای آیتم باید قرار بگیرد.

امیدوارم تونسته باشم خوب شرح بدم. ممنون میشم استاد راهنمایی کنید.

محمد سلیم آبادی
یک شنبه 24 دی 1391, 21:43 عصر
دوست عزیز این کوئری رو امتحان کنید:
SELECT * FROM table_name
WHERE HeaderID IN (SELECT headerID FROM table_name WHERE Description LIKE '%pump%')
ORDER BY HeaderID, Line;

البته تا اونجایی که یادم میاد در تاپیکی که قبلا ایجاد کردی همچین کوئری وجود داشت...

mohsen_zelzela00
یک شنبه 24 دی 1391, 22:19 عصر
دوست عزیز این کوئری رو امتحان کنید:
SELECT * FROM table_name
WHERE HeaderID IN (SELECT headerID FROM table_name WHERE Description LIKE '%pump%')
ORDER BY HeaderID, Line;

البته تا اونجایی که یادم میاد در تاپیکی که قبلا ایجاد کردی همچین کوئری وجود داشت...

ممکنه که خود آیتم ها هم در شرح کالای آن کلمه PUMP وحود داشته باشه ولی این فقط برای هدرها است

محمد سلیم آبادی
یک شنبه 24 دی 1391, 22:29 عصر
ممکنه که خود آیتم ها هم در شرح کالای آن کلمه PUMP وحود داشته باشه ولی این فقط برای هدرها است
شما کوئری رو تست کردین یا نه؟
در subquery هدرآیدی هایی انتخاب میشن که دارای مقدار pump در ستون description باشن حالا چه از نوع H و چه از نوع L.
وقتی که از نوع L باشن خود L همراه با H مرتبط انتخاب میشه. اگه از نوع H باشن تمام L ها هم انتخاب بای بشه.

mohsen_zelzela00
یک شنبه 24 دی 1391, 22:42 عصر
شما کوئری رو تست کردین یا نه؟
در subquery هدرآیدی هایی انتخاب میشن که دارای مقدار pump در ستون description باشن حالا چه از نوع H و چه از نوع L.
وقتی که از نوع L باشن خود L همراه با H مرتبط انتخاب میشه. اگه از نوع H باشن تمام L ها هم انتخاب بای بشه.

بله استاد تست کردم ولی یه مشکلی داره که الان توضیح میدم فقط قبل از اینکه عکس بزارم یه متنی رو از پست قبل کپی می کنم


حال با توجه به این کار من پارامتر زیر را سمت SP مورد نظر ارسال می کنم






(Description LIKE '%pump%')',1,100




حال با توجه به این پارامترها 1 به معنی صفحه اول است و 100 به معنی اینکه در هر صفحه 100 رکورد وجود دارد نوبت به شرح کالا می رسد که می گوید شرح کالا باید حاوی PUMP باشد. برای این مورد می توان دو حالت در نظر گرفت.

حالت اول: ممکن است که کلمه PUMP در شرح کالای رکورد هدر باشد(line=H): در این حالت هدر و تمام آیتم های آن هدر انتخاب می شوند

حالت دوم: ممکن است که کلمه PUMP در شرح کالای آیتم ها باشد: در این صورت آن آیتمی که شرح کالای آن حاوی PUMP است + هدر آن انتخاب می شود.

زمانی که این Query رو اجرا می کنم خروجی زیر را مشاهده می کنم
98363

اگر به رکورد 7 دقت کنیم می بینیم که حاوی کلمه PUMP است پس جز خروحی اومده و تمام هدرهای آن هم لیست شدند ولی آیتم 8 دارای کلمه PUMP نیست و نباید در خروجی ظاهر می شود(قرار بر این بود که وقتی PUMP در آیتم پیدا شد فقط اون آیتم و هدرهای آن نمایش داده شوند در صورتی که الان تمام هدرها و تمام آیتم ها نمایش داده می شوند)

mohsen_zelzela00
یک شنبه 24 دی 1391, 23:03 عصر
من با اجازتون یه قسمتی از کد رو به این صورت نوشتم


SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM Report2
WHERE HeaderID IN (SELECT headerID FROM Report2 WHERE Discription LIKE '%pump%' and Line='h')
ORDER BY HeaderID, Line,Unit;


البته این فقط روی هدرها درست کار می کند حال باید برای آیتم ها نیز شرطی اعمال کرد که این Query کامل شود.

ممنون میشم باز هم من رو راهنمایی کنید.

mohsen_zelzela00
یک شنبه 24 دی 1391, 23:09 عصر
استاد من تونستم Query زیر رو واسه کارم در بیارم یه جورایی درست جواب میده

SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM Report2
WHERE
HeaderID IN (SELECT headerID FROM Report2 WHERE Discription LIKE '%pump%' and Line='h') or
Mesc in( SELECT Mesc FROM Report2 WHERE Discription LIKE '%pump%' and Line='i') or
Mesc in(SELECT HeaderId FROM Report2 WHERE Discription LIKE '%pump%' and Line='i')
ORDER BY HeaderID, Line,Unit;


فقط آیا میشه این Query رو بهینه تر یا به صورت بهتر نوشت؟ ممنون میشم راهنمایم کنید.

mohsen_zelzela00
یک شنبه 24 دی 1391, 23:25 عصر
زمانی که این Query را اجرا میکنم یه چیزی حدود 1000000 رکورد را در عرض 5 ثانیه برای من لود می کنه

SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM Report2
WHERE
HeaderID IN (SELECT headerID FROM Report2 WHERE Discription LIKE '%pump%' and Line='h') or
Mesc in( SELECT Mesc FROM Report2 WHERE Discription LIKE '%pump%' and Line='i') or
Mesc in(SELECT HeaderId FROM Report2 WHERE Discription LIKE '%pump%' and Line='i')
ORDER BY HeaderID, Line,Unit;


حال می خواهم این داد ها را صفحه بندی کنم برای صفحه بندی کردن من کد بالا را به صورت زیر تغییر دادم

select [Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
from (
SELECT Distinct
[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
, ROW_NUMBER() OVER(ORDER BY Mesc,Line,unit ) ROW_NUM
FROM Report2
WHERE
HeaderID IN (SELECT headerID FROM Report2 WHERE Discription LIKE '%pump%' and Line='h') or
Mesc in( SELECT Mesc FROM Report2 WHERE Discription LIKE '%pump%' and Line='i') or
Mesc in(SELECT HeaderId FROM Report2 WHERE Discription LIKE '%pump%' and Line='i') )a where ROW_NUM between 100 and 200


با توجه به اینکه فقط قراره 100 رکورد رو لود کنه یه چیزی حدود 2 دقیقه اجرا شدنش طول می کشه آیا می توان یه کاری کرد که زمان آن را کاهش داد(فکر می کنم این کدی که من واسه صفحه بندی نوشتم زیاد بهینه نیست) ممنون میشم کمکم کنید که این کد رو اصلاح کنم. ممنون

محمد سلیم آبادی
یک شنبه 24 دی 1391, 23:28 عصر
فعلا نتونستم منطق ساده شده تر از این براش پیدا کنم.
امتحانش کنید:
SELECT SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM report2 as r1
WHERE exists
(select * from report2 as r2
where r1.line = 'h'
and r2.line ='i'
and r2.Description LIKE '%pump%'
and r1.headerID=r2.headerID)
or exists
(select * from report2 as r3
wher r1.line='i'
and r3.line='h'
and r1.headerID=r3.headerid
and r3.Description LIKE '%pump%')
or description like '%pump%'
ORDER BY HeaderID, Line, unit;

mohsen_zelzela00
یک شنبه 24 دی 1391, 23:43 عصر
فعلا نتونستم منطق ساده شده تر از این براش پیدا کنم.
امتحانش کنید:
SELECT SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM report2 as r1
WHERE exists
(select * from report2 as r2
where r1.line = 'h'
and r2.line ='i'
and r2.Description LIKE '%pump%'
and r1.headerID=r2.headerID)
or exists
(select * from report2 as r3
wher r1.line='i'
and r3.line='h'
and r1.headerID=r3.headerid
and r3.Description LIKE '%pump%')
or description like '%pump%'
ORDER BY HeaderID, Line, unit;

استاد چیزی که من به کمک شما نوشتم سریع تر جواب میده یا این؟؟ ممنون میشم واسه صفحه بندی هم من روراهنمایی کنید.

محمد سلیم آبادی
یک شنبه 24 دی 1391, 23:48 عصر
بحث سر اینه که آیا اون چیزی که شما نوشتین صحیح هست و خروجی مورد نظر رو تولید می کنه یا نه.
ضمن اینکه باید دید کوئری که من نوشتم همونی هست که شما میخواهین. آیا امتحانش کردین؟
من شک دارم اون چیزی که شما نوشتین خروجی مطلوب رو تولید کنه.

mohsen_zelzela00
یک شنبه 24 دی 1391, 23:57 عصر
بحث سر اینه که آیا اون چیزی که شما نوشتین صحیح هست و خروجی مورد نظر رو تولید می کنه یا نه.
ضمن اینکه باید دید کوئری که من نوشتم همونی هست که شما میخواهین. آیا امتحانش کردین؟
من شک دارم اون چیزی که شما نوشتین خروجی مطلوب رو تولید کنه.

Query که من نوشتم خروجی آن 11149 رکورد است و Query شما 5859 رکورد است. حالا استاد به نظر شما چگونه می تونم صحت این دو رو چک کنم؟

محمد سلیم آبادی
دوشنبه 25 دی 1391, 00:03 صبح
منطق کوئری که من نوشتم به این شرح هست (اگه اشتباه هست که کوئری هم اشتباه باید باشه):
اگر سطر H بود آنگاه باید پیدا شود در جدول سطری که I باشد و کلمه Pump در آن یافت شود یا
اگر سطر I بود آنگاه باید پیدا شود در جدول سطری که H باشد و کلمه Pump در آن یافت شود یا
کلمه Pump در آن یافت شود (صرف نظر از اینکه I هست یا H).

توجه داشته باشید:
برای تسریع در اجرای کوئری (اعمال ranking) پیشنهادی دارم که اجراش کنید:
کلمه distinct را از کوئری داخلی حذف کنید و تابع row_number رو با تابع dense_rank تعویض کنید.
سپس در کوئری بیرونی دستور distinct رو لحاظ کنید. چیزی شبیه به این:

select distinct .... from (select ..., dense_rank() over(order by...) as rnk from report2)d where ... and rnk between 100 and 200

mohsen_zelzela00
دوشنبه 25 دی 1391, 00:22 صبح
منطق کوئری که من نوشتم به این شرح هست (اگه اشتباه هست که کوئری هم اشتباه باید باشه):
اگر سطر H بود آنگاه باید پیدا شود در جدول سطری که I باشد و کلمه Pump در آن یافت شود یا
اگر سطر I بود آنگاه باید پیدا شود در جدول سطری که H باشد و کلمه Pump در آن یافت شود یا
کلمه Pump در آن یافت شود (صرف نظر از اینکه I هست یا H).


فکر کنم هر دو Query یه مشکلی داشته باشند
مثلاً مشکل Query شما:

98367

اگر به رکورد 64 توجه کنید فقط یک هدر اورده که اونم دارای کلمه pump هست در صورتی که ما می خواهیم زمانی که pump درون هدر باشد هدرها و تمام آیتم های آن هدر را نمایش دهد(ممکن است هدر در چند رکورد شکسته شود در این صورت مقدار فیلد MESC , HeaderId آنها برابر است).
و این هم من در جدول اصلی این کد را واکشی کردم

98368

آبا می شود این رو هم اصلاح کرد؟

محمد سلیم آبادی
دوشنبه 25 دی 1391, 00:31 صبح
اوکی من به این مطلب توجه نکرده بودم:
هنگامی که هدر بود تمام هدرها و آیتم ها انتخاب شون. من فک میکردم فقط آن هدر با تمام آیتم هایش!
این و امتحان کنید و همچنین در نظر داشته باشین من در آستانه سکته زدن هستم:عصبانی++:
SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM report2 as r1
WHERE exists
(select * from report2 as r2
where r1.line = 'h'
and r2.Description LIKE '%pump%'
and r1.headerID=r2.headerID)
or exists
(select * from report2 as r3
where r1.line='i'
and r3.line='h'
and r1.headerID=r3.headerid
and r3.Description LIKE '%pump%')
or description like '%pump%'
ORDER BY HeaderID, Line, unit;

mohsen_zelzela00
دوشنبه 25 دی 1391, 00:33 صبح
توجه داشته باشید:
برای تسریع در اجرای کوئری (اعمال ranking) پیشنهادی دارم که اجراش کنید:
کلمه distinct را از کوئری داخلی حذف کنید و تابع row_number رو با تابع dense_rank تعویض کنید.
سپس در کوئری بیرونی دستور distinct رو لحاظ کنید. چیزی شبیه به این:

select distinct .... from (select ..., dense_rank() over(order by...) as rnk from report2)d where ... and rnk between 100 and 200
واقعاً سرعتش فوق العاده است از 2 دقیقه به 15 ثانیه رسید واقعاً ممنونم

mohsen_zelzela00
دوشنبه 25 دی 1391, 00:45 صبح
اوکی من به این مطلب توجه نکرده بودم:
هنگامی که هدر بود تمام هدرها و آیتم ها انتخاب شون. من فک میکردم فقط آن هدر با تمام آیتم هایش!
این و امتحان کنید و همچنین در نظر داشته باشین من در آستانه سکته زدن هستم:عصبانی++:
SELECT [Id]
,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[HeaderId]
FROM report2 as r1
WHERE exists
(select * from report2 as r2
where r1.line = 'h'
and r2.Description LIKE '%pump%'
and r1.headerID=r2.headerID)
or exists
(select * from report2 as r3
where r1.line='i'
and r3.line='h'
and r1.headerID=r3.headerid
and r3.Description LIKE '%pump%')
or description like '%pump%'
ORDER BY HeaderID, Line, unit;

استاد چرا سکته؟ خدا نکنه.
الان که تست کردم هر دو Query دارن یک نتیجه رو بر گشت می دن هر دو 11149 رکورد برگشت میدن .
یه دنیا ممنونم استاد کاش می تونستم به یه طریق دیگه از شما تشکر کنم خدا عمرتون بده.