שאלה של מתחיל

כלליים

New member
שאלה של מתחיל

בתחביר SQL של אקסס, אני יכול לפנות לשדות השאילתה באותה שאילתה עצמה. למשל:
select 100 AS expr1, exp1 * 2 as expr2​
וכן:
SELECT Sum(Transactions.BuyerPrice) AS Total, [Total] / 1.16 AS Net FROM Transactions;​
ניסיתי לבצע דבר דומה בT-sql, ונחלתי כשלון חרוץ.. מהו התחביר? תודה רבה.
 

pitoach

New member
3 דרכים נפוצות:

1. במקום לרשום [Total] / 1.16 תרשום שוב את החלק של ה Total ז"א: Sum(Transactions.BuyerPrice)/1.16 2. שימוש בשאילתה פנימית.. תכניס את התוצאה הראשונית לסוגריים ובצע שאילתה מתוך התוצאה של השאילתה הקודמת 3. עבודה עם CTE (אני לא מפרט מפני שזה לוגיקה אחרת ואם כי מומלץ מאוד ללמוד וזו הדרך שכניראה רוב ה DBA יבחרו הרי שזה משהו חדש למיש עובר מאקסס ואם לא רוצים ללמוד את זה כרגע אז 2 הפתרונות מעל יעזרו)... אם אתה רוצה פירוט על CTE תגיד כמובן
 

כלליים

New member
כל הדרכים מובילות לרומא..

ראשית, אני מודה לך על התשובה. אולי תופתע, אבל הדרך השלישית היא זו שיושמה.. הדרך הראשונה היא הפשוטה, ואותה כמובן הכרתי, אלא שהיא לא אלגנטית, במיוחד כשמדובר בחישובים מורכבים, ובמיוחד לאור מאמר של גרי רשף שטוען שהפונקציות מחושבות שוב ושוב, שלא לצורך. את הדרך השניה, ניסיתי ליישם אבל לא הצלחתי למצוא את התחביר המדויק. כתבת שדי להכניס את החישוב לסוגריים, האם אינני צריך לכלול אותו במקטע FROM? איך אני מיישם את זה על הדוגמא הטריוויאלית שנתתי קודם? ניסיתי בכמה אופנים ולא הצלחתי. אינך צריך לטרוח לענות לי, כי זה לא המקום ללימוד בסיסי של השפה, אבל אם תענה, כמובן שזה יתקבל בברכה
הדרך השלישית, כמובן היא הנקיה והיפה מכולם.
 

כלליים

New member
מכל הלב

אני מעט מתפלא על עצמי, כי על הדרך השניה, הייתי אמור לחשוב על-סמך נסיוני באקסס, ואף-על-פי-כן, היא לא עלתה על דעתי. נו. למעשה, במקרה הספציפי שלנו, שתי הדרכים מתלכדות, אלא שבדרך השלישית מכריזים מלכתחילה על השאילתה. אני מניח שבהמשך דרכי אעמוד על המשמעויות וההבדלים. תודה רבה ושבוע טוב.
 

כלליים

New member
ולבסוף

בחרתי בדרך חמישית: טבלה זמנית. הסיבה: מכיוון שבSP היה עלי להשתמש בIFים, וCTE איננו תומך בזה [על-פי מה שמצאתי בגיגול מהיר], השתמשתי בפתרון הזה. אגב: גם את צורת השימוש בטבלה זמנית למדתי מדבריך...
 

pitoach

New member
כמה נקודות

1. CTE בהחלט מאפשר שימוש ב IF הן בתוך השאילתה של ה CTE וכן בשימוש בטבלה של ה CTE בשאילתה הראשית הנה סתם דוגמה קטנה (אין בכלל חשיבות לתוצאה וסתם כתבתי משהו להראות שאין שגיאה ויש תוצאות נהדרות) ;with MyCTE (FixedPrice) as ( SELECT CASE WHEN Price < 20 THEN Price ELSE 0 END as FixedPrice FROM @Tbl ) select Sum(FixedPrice) SumFixedPrice ,CASE WHEN FixedPrice = 45 THEN FixedPrice ELSE 999 END as FixedPrice from MyCTE group by FixedPrice 2. טבלה זמנית היא פתרון טוב שתמיד צריך לחשוב עליו לעומק. אחרי הכל יש הרבה מאוד נתונים בטבלה הזמנית שיכולים ליצור בעיות מיטוב בהמשך כגון (וזה רק מקצת על קצה קצהו של המזלג): * לטבלה הזמנית אין אינדקסים ואים בונים אינדקסים אז יש לבנות אותם מחדש בכל פעם שבונים את הטבלה * יצירת הבטלה הזמנית לוקחת משאבים בפני עצמה. * הטבלה הזמנית אינה מוכרת למנוע המיטוב ולכן חסרים לו סטטיסטיקות לקבוע את תוכנית ההרצה מיטבית בדרך כלל * לבטלה זמנית יש סקופ (אזור שהחיא קיימת) כך למשל ניתן ליצור טבלה זמנית ברמת סשן של משתמש או טבלה זמנית גלובלית ועוד.. * שימוש בטבלה זמנית פיזית לא מאפשר למנוע המיטוב לקחת את השאילתה המבוקת ולפרט אותה לרכיבים. ז"א אם בשאילתה רגילה ביצענו שאילתה בתוך שאילתה בעזרת סוגריים הרי שמנוע המיטוב לא בהכרח אכן ביצע את התהליך ב 2 שלבים וזהו רק תהליך לנוחיות שהסברנו בהודעה הקודמת. עם זה בטבלה זמנית אנו מייצרים אותה פיזית ולכן תמיד התהליך יפורק ל 2 השלבים (לפחות). ** ועוד... ___ לסיכום ____ למרות כל הכתוב כאן אני לא פוסל כמובן טבלה זמנית וזה פתרון נוסף (ויש עוד הרבה). בלי אפיון מלא של הבעיה האמיתי אנחנו רק מדברים באוויר על אפשרויות ואני רק מעלה נקודות שיש לחשוב ולהתחשב בהן באפיון
 

כלליים

New member
אכן

ידעתי לשלב CASE בתוך חישוב של שדה ספציפי, אבל למשל אי אפשר:
with T as (select a,b,c from table) if @varname = 1 select a, sum(c) ftom T group by a if @varname = 2 select b, sum(c) ftom T group by b​
אמנם, אני יכול להשתמש בCASE, אבל יהא עלי לחזור עליו גם בSELECT וגם בgroup by, ושוב קבלתי קוד מסובך. בSP שלי, אמנם הטבלה המקורית היא בת מליוני רשומות, אבל מכיוון שאני מחזיר סכומי שדות, בסוך אני מקבל רשומות בודדות בסך הכל, ולכן אני משער שאין משמעות קריטית לטבלה הזמנית. אמנם פחות או יותר השאילתה הורצה בהצלחה, ואין לי סיבה להטריח אותך להזדקק לה, אפילו הכי צרפתי אותה, ומיד אצרף גם DDL.
 

כלליים

New member
DDL. ושוב:

כמובן אין סיבה להטריח אותך לצלול למעמקי "כוונת המשורר". בעיקר באתי להראות את המורכבות של השאילתה, שעל סמך פרמטר יחיד היא אמורה לשנות מהותית את מבנה התוצאות המוחזרות. המטרה של השאילתה היא לסכם מכירות של חברה קמעונאית שמשווקת מוצרים ממספר ספקים. נשלח פרמטר יחיד שקובע איזה ספק רוצים לסכם. הבעיה: כדי לזהות עסקה [עסקה = רשומה בטבלת transactions], בתור עסקה ששיכת לספק מסוים, צריך IF: לעיתים הזיהוי הוא על סמך המוצר, לעיתים על-סמך המסוף שבו נעשתה העסקה וכו'. מלבד זאת יש חישובים נוספים שתלויים במספר רב של 'קייסים'. ושוב תודה מכל הלב.
 
למעלה