PDA

View Full Version : مشکل با عبارت GROUP BY



hamid-nic
پنج شنبه 12 آذر 1388, 13:48 عصر
سلام و وقتتان بخیر دوستان عزیز
فرض کنید یک جدولی داریم که شامل اطلاعات پول های پرداخت شده توسط افراد است . یعنی حداقل فیلدی به نام مبلغ و فیلد ماه پرداخت در آن وجود دارد . (جدای از سایر فیلد ها )
حال با این فرض که یک شخص در هر ماه که در جدول بصورت اعداد (مثلا ماه 1 یا 2 و ...) مشخص شده است تعداد زیادی رکورد پرداخت پول دارد . یعنی به عنوان مثال در ماه 1 تعداد 5 رکورد پرداخت شده و در ماه 2 تعداد 3 رکورد پرداخت و به همین صورت سایر ماه های سال هم برای هر ماه تعدادی و یا اصلا رکورد پرداختی ندارد .
حالا سوال اینجاست که :
چگونه برای هر ماه بتوانیم جمع پول های پرداخت شده را در یک رکورد بدست آوریم . یعنی با انجام یک کوئری بتوانیم حاصل تمام این رکورد ها را که بر اساس ماه ذخیره شده است با تفکیک ماه بدست آوریم . به عنوان مثال اگر شخصی در ماه 1 تعداد 5 رکورد پرداخت دارد حاصل جمع پول های این 5 رکورد را در یک رکورد با شناسه ی ماه 1 درج کند و برای سایر ماه ها هم همچنین .
به عنوان مثال :



فایل ضمیمه به نام Befor




حاصل کوئری به این شکل باشد



فایل ضمیمه به نام After

محمد سلیم آبادی
پنج شنبه 12 آذر 1388, 17:16 عصر
سلام دوست عزیز،
تنها کافیست بر اساس دو ستون کد شخص و ماه گروه بندی کنین و از تابع sum روی ستون مبلغ استفاده کنین.

hamid-nic
پنج شنبه 12 آذر 1388, 18:19 عصر
سلام دوست عزیز،
تنها کافیست بر اساس دو ستون کد شخص و ماه گروه بندی کنین و از تابع sum روی ستون مبلغ استفاده کنین.
من این کار را کردم اما مشکل این است که فیلدی که به عنوان جمع روی ستون مبلغ استفاده می کنم جمع کل رکورد های اون شخص را محاسبه می کند ولی من می خواهم به تفکیک ماه جمع هر کدوم را انجام دهد نه اینکه تمام رکورد های اون شخص را جمع بزند.

محمد سلیم آبادی
پنج شنبه 12 آذر 1388, 18:55 عصر
لطفا query که برای این منظور استفاده می کنید را ارسال کنین.

hamid-nic
پنج شنبه 12 آذر 1388, 21:11 عصر
لطفا query که برای این منظور استفاده می کنید را ارسال کنین.
برای مثال بالا کوئری زیر را نوشتم که جواب داد



Select Sum(dbo.test.pool) as Kol , dbo.test.id , dbo.test.mount
from dbo.test
group by dbo.test.id , dbo.test.mount


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



SELECT SUM(dbo.MainFish.pool) AS kol, dbo.MainInf.code, dbo.MainInf.name, dbo.MainInf.Family, dbo.MainInf.nameFather, dbo.MainInf.WorkTime,
dbo.ReshtehHa.reshteh, dbo.MainKh.status, dbo.MainKh.sal, dbo.Status.namestatus
FROM dbo.MainInf INNER JOIN
dbo.MainFish ON dbo.MainInf.code = dbo.MainFish.code INNER JOIN
dbo.ReshtehHa ON dbo.MainInf.reshteh = dbo.ReshtehHa.ID INNER JOIN
dbo.MainKh ON dbo.MainInf.code = dbo.MainKh.code INNER JOIN
dbo.Status ON dbo.MainKh.status = dbo.Status.status
GROUP BY dbo.MainInf.code, dbo.MainInf.name, dbo.MainInf.Family, dbo.MainInf.nameFather, dbo.MainInf.WorkTime, dbo.ReshtehHa.reshteh,
dbo.MainKh.status, dbo.Status.namestatus, dbo.MainKh.sal


که منظورم از فیلد ماه (در مثال قبلی ) در اینجا Dbo.mainkh.sal
.. منظورم از فیلد پول (در مثال قبلی ) در اینجا Dbo.mainfish.pool
.. منظورم از فیلد کد شخص (در مثال قبلی ) در اینجا Dbo.maininf.code
می باشد .
لطفا راهنمایی کنید .

محمد سلیم آبادی
پنج شنبه 12 آذر 1388, 22:07 عصر
اینجوری نمیشه، باید بانکتون رو یا script اش رو ضمیمه کنین. یا حد اقل لیست ستون های جداول، کلیدهای اصلی و خارجی (با ذکر references) رو مشخص کنین و یک نمونه از داده ها و یک نمونه از خروجی مورد نظر رو ارسال کنین.

hamid-nic
پنج شنبه 12 آذر 1388, 22:45 عصر
اینجوری نمیشه، باید بانکتون رو یا script اش رو ضمیمه کنین. یا حد اقل لیست ستون های جداول، کلیدهای اصلی و خارجی (با ذکر references) رو مشخص کنین و یک نمونه از داده ها و یک نمونه از خروجی مورد نظر رو ارسال کنین.

این دیاگرام کوئری پست قبل است. میشه کاری کرد با این ؟ کلید های اصلی با نام جداول را مشخص کردم .
منظور از فیلد Sal ترم تحصیلی است.

محمد سلیم آبادی
پنج شنبه 12 آذر 1388, 23:19 عصر
اینو امتحان کن:


select M.code,
M.sal,
D.S,
M.name,
M.family,
M.nameFather,
M.workTime,
K.status,
S.namestatus,
R.reshteh
from (select code, sal, SUM(pool) as S
from MainFish
group by code, sal) as D
inner join MainInf as M
on D.code = M.code
inner join ReshtehHa as R
on M.reshteh = R.reshteh
inner join MainKh as K
on M.sal = K.sal
and M.code = K.code
inner join Status as S
on K.status = S.status

hamid-nic
جمعه 13 آذر 1388, 18:39 عصر
سلام
شرمنده از اینکه دیر شد
کدتون را امتحان کردم در Query Analyzer .
خطای نوشتاری نداشت اما وقتی آن را اجرا کردم خطای زیر را داشت :



Server: Msg 245, Level 16, State 1, Line 1
Syntax error converting the nvarchar value 'حسابداري ' to a column of data type smallint.

محمد سلیم آبادی
جمعه 13 آذر 1388, 20:17 عصر
باید دنبال ستونی بگردین که مقدار "حسابداری" در اون درج شده. احتمال می دم ستون ها اشتباهی با همدیگه مقایسه میشن (در قسمت join-conditions).
این error بر میگرده به convert. باید هنگام بررسی تساوی دو ستون در قسمت join-condition این اتفاق بی افته.

hamid-nic
جمعه 13 آذر 1388, 23:56 عصر
دقیقا حدس شما درست بود .
کد را با دقت نگاه کردم دیدم توی join ها یک ستون اشتباه اومده که در زیر با رنگ قرمز مشخص کردم+یک ستون در اول لیست (البته این درست شده است )
کوئری را اجرا کردم اجرا شد اما با مشکل جدید :
مشکل اصلی که همون جمع پول بود درست شد اما من یک نمونه از داده ها که به ورودی می دهیم و یک نمونه از خروجی با کد جدید را می گذارم که متوجه مشکل بشوید .




select M.code,
k.sal,
D.S,
M.name,
M.family,
M.nameFather,
M.workTime,
K.status,
S.namestatus,
R.reshteh
from (select code, sal, SUM(pool) as s
from MainFish
group by code, sal) as D
inner join MainInf as M
on D.code = M.code
inner join ReshtehHa as R
on M.reshteh = R.id
inner join MainKh as K
on M.code = K.code
inner join Status as S
on K.status = S.status

داده های ورودی در ضمیمه به نام Inpute
خروجی با کد اصلاح شده در ضمیمه به نام output 1
در صورتی که خروجی باید به این شکل باشد >> Output 2

محمد سلیم آبادی
شنبه 14 آذر 1388, 05:19 صبح
اینو امتحان کنین بلکه نتیجه مورد نظر بدست بیاد:



select M.code,
k.sal,
D.S,
M.name,
M.family,
M.nameFather,
M.workTime,
K.status,
S.namestatus,
R.reshteh
from MainInf as M
left outer join MainKh as K
on M.code = K.code
left outer join ReshtehHa as R
on M.reshteh = R.id
left outer join (select code, sal, SUM(pool) as s
from MainFish
group by code, sal) as D
on D.code = M.code
and D.sal = K.sal
left outer join Status as S
on K.status = S.status

hamid-nic
شنبه 14 آذر 1388, 09:54 صبح
خیلی خیلی ممنون
تنها استفاده کردن از دکمه ی تشکر برای این کمک کافی نیست امیدوارم همیشه موفق باشید .
راستی چند تا سوال در مورد این کد داشتم .

اینکه آیا این Left Join ها معادل Inner Join ها است ؟
نام ستون جمع پول را نمی توان تغییر داد ؟
این حروف مخفف در ابتدای نام ستون ها و جا های دیگه ی کد برای چیه ؟
و در کد که در زیر آمده است قسمت D.s (خط سوم) برای چیه ؟

بازم از کمکتون خیلی ممنونم .




select M.code,
k.sal,
D.S,
M.name,
M.family,
M.nameFather,
M.workTime,
K.status,
S.namestatus,
R.reshteh
from MainInf as M
left outer join MainKh as K
on M.code = K.code
left outer join ReshtehHa as R
on M.reshteh = R.id
left outer join (select code, sal, SUM(pool) as s
from MainFish
group by code, sal) as D
on D.code = M.code
and D.sal = K.sal
left outer join Status as S
on K.status = S.status

محمد سلیم آبادی
شنبه 14 آذر 1388, 10:19 صبح
اینکه آیا این Left Join ها معادل Inner Join ها است ؟

left join بطور خلاصه: تمام سطرهای جدول سمت چپ را انتخاب کرده و از سطرهای جدول سمت راست آنهایی که match می شوند را انتخاب می کند...

نام ستون جمع پول را نمی توان تغییر داد ؟
ستون مربوط به جمع پول D.s نام داره که با کمک AS می توانین نام مستعار دلخواه بدهین.

این حروف مخفف در ابتدای نام ستون ها و جا های دیگه ی کد برای چیه ؟

این ها نام مستعار هستند که به جداول داده شده اند که به منظور راحتتر شدن تایپ اینکار را کردم ولی بعضی مواقع مثلا join جدول با خودش حتما نیاز به نام مستعار برای تفکیک جداول دارد.

و در کد که در زیر آمده است قسمت D.s (خط سوم) برای چیه ؟

این همان ستون جمع پولهاست. که از جدول مشتق شده ی D بدست میاد.