en-UShe-IL
You are here:  Blog > new Forums FAQ > Forums FAQ 353
Register   |  Login

Minimize Enter Title

  

תחילה DDL שנדע על מה אני מדבר

declare @Tbl as table (Price int)
 
insert @Tbl
select 10 union
select 13 union
select 22 union
select 45 union
select 21


הדרך הראשונה היתה כאמור
SELECT Sum(Price) AS Total, Sum(Price) / 1.16  AS Net FROM @Tbl;


הדרך השלישית היא כאמור
;with
MyCTE (Total)
as
(SELECT Sum(Price) AS Total FROM @Tbl)
select Total,Total/1.16 from MyCTE


ונעבור לדרך שנשארה:
הדרך השנייה מאוד פשוטה והיא למעשה בסיס חשוב לשאילתות מורכבות. היא לא מביאה את המיטוב בדרך כלל ומתבססת על היכולת של מנוע המיטוב לבנות לנו שאילתה מיטבית מהלוגיקה שלנו. הלוגיקה היא לפרק שאילתות לתת שאילתות שקל יותר להבין

למשל קל לראות שאם היה לנו את ה Total אז היינו יכולים לקבל ממנו אחר כך את הנתון של ה Total/1.16

לכן ניתן להוציא קודם
SELECT Sum(Price) AS Total FROM @Tbl


ועתה נכניס את התוצאה לסוגריים לניתוח נוסף ולמעשה נוציא מתוך התוצאת ביניים את התוצאה הסופית:
select Total, Total/1.16 from
(SELECT Sum(Price) AS Total FROM @Tbl) as Tbl


* כאמור זו דרך שמאוד כדאי להכיר מפני שככה אפשר להגיע לשאילתות מאוד מורכבות (ואני שוב אומר שאולי לא נגיע לפתרון מיטבי אבל נגיע לפתרון בדרך כלל לכל בעיה)

*** לגבי הטענה של חישוב כפול:
1. אתה מוציא בסך הכל תוצאה אחת מכל הרשומות ולכן אין חשיבות כל כך.
2. מנוע המיטוב יודע במקרים בהם החישוב אינו תלוי ברשומות לא לבצע את החישוב כמה פעמים (יוצא מהכלל זה פונקציית NEWID). כך למשל אם תשתמש בשרת SQL בפונקציה RAND() תקבל בכל הרשומות מספר רנדומלי אבל את אותו מספר כי החישוב מבוצע בהתחלה עבור כל הרשומות. לעומת זאת אם תעשה חישוב מותנה ברשומה כמו סינוס למשל sin(Price) אז תקבל חישוב מחדש בכל רשומה.
* דבר זה אינו נכון לשרתים אחרים! ב MYSQL למשל ההתנהגות שונה.

במקרים בהם רוצים לבצע חישוב של נתון בודד עבור כל הרשומות תמיד אפשר להוציא אותו החוצה כמשתנה ואז להישתמש בו. למשל (וזה פתרון רביעי לדוגמה ויש עוד הרבה אפשרויות):
declare @Total as float
select @Total = Sum(Price) FROM @Tbl
select @Total,@Total/1.16