תחילה 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