שאילתת SQL חצויה
-
לחכמי הSQL.
להלן שאילתא שנותנת מידע על המתקשרים מתוך טבלא שנרשמת שם שורה בכל התקשרות, JOIN עם טבלא של שמות של המתקשריםSELECT CONCAT('="', CDR_GLOBAL.src, '"') AS phone, TRUECALLER.name AS name, MIN(CDR_GLOBAL.calldate) AS firstCall, MAX(CDR_GLOBAL.calldate) AS lastCall, ROUND(SUM(CDR_GLOBAL.billsec)/60) AS minuts, COUNT(CDR_GLOBAL.id) AS calls FROM ICALL.CDR_GLOBAL LEFT JOIN ICALL.TRUECALLER ON TRUECALLER.phone=CDR_GLOBAL.src WHERE did IN(07212345678,07212345679) GROUP BY CDR_GLOBAL.src ORDER BY calls DESC
השאילתא עובדת מצוין, והיא מחזירה את רשימת המתקשרים עם מידע על כל אחד, מתי חייג לראשונה, מתי לאחרונה, כמות דקות וסך התקשרויות.
עכשיו אני רוצה לצמצם את זה לחודש אחד, אבל שיופיע עדיין מתי התקשר לראשונה כללי ולא רק ביחס לחודש הזה
אבל כשאני כותב בWHEREWHERE calldate >= '2020-05-01 00:00:00' AND did IN(07212345678,07212345679)
זה גם כמובן מגביל את הMIN(CDR_GLOBAL.calldate)
אשמח לרעיון איך לעשות בשאילתא אחת צמצום שיתן רק סך דקות והתקשרויות של החודש הנוכחי אבל עדיין יתן התקשרות ראשונה כללית.
תודהעריכת הסבר, הCONCAT בשורה הראשונה, זה כי זה נכתב בקובץ CSV, וזה פטנט להצגת ה0 בתחילת המספר טלפון.
-
SELECT CONCAT('="', T1.src, '"') AS phone, TRUECALLER.name AS name, (SELECT MIN(calldate) FROM ICALL.CDR_GLOBAL WHERE src = T1.src) AS firstCall, MAX(T1.calldate) AS lastCall, ROUND(SUM(T1.billsec)/60) AS minuts, COUNT(T1.id) AS calls FROM ICALL.CDR_GLOBAL AS T1 LEFT JOIN ICALL.TRUECALLER ON TRUECALLER.phone=T1.src WHERE did IN(07212345678,07212345679) GROUP BY T1.src ORDER BY calls DESC
או
SELECT CONCAT('="', T1.src, '"') AS phone, TRUECALLER.name AS name, FirstT.First , MAX(T1.calldate) AS lastCall, ROUND(SUM(T1.billsec)/60) AS minuts, COUNT(T1.id) AS calls FROM ICALL.CDR_GLOBAL AS T1 LEFT JOIN ICALL.TRUECALLER ON TRUECALLER.phone=T1.src LEFT JOIN (SELECT src, MIN(calldate) as First FROM ICALL.CDR_GLOBAL GROUP BY src) as FirstT ON T1.src = FirstT.src WHERE did IN(07212345678,07212345679) GROUP BY T1.src ORDER BY calls DESC
תעדכן מה יותר מהר...
-
@שואף אמר בשאילתת SQL חצויה:
@dovid אמר בשאילתת SQL חצויה:
אלא"כ עדכנת?
אבל אני רואה שהברירת מחדל היא 5.7, כך שכנראה זה הגרסא היציבה
הגירסה היציבה היא 8.0.20 אבל משום מה אובנטו לא זזים מהר, צריך לעשות צעד לפני ההתקנה כדי לרשום את מקור החבילה לגירסה החדשה.
טוב, אז אתה יכול לשכוח מהפתרון של window functions. -
נסיון לפתור בצורה אחרת:
SELECT CONCAT('="', CDR_GLOBAL.src, '"') AS phone, TRUECALLER.name AS name, MIN(CDR_GLOBAL.calldate) AS firstCall, MAX(CDR_GLOBAL.calldate) AS lastCall, ROUND(SUM(CASE WHEN CDR_GLOBAL.calldate >= '2020-05-01 00:00:00' THEN CDR_GLOBAL.billsec ELSE 0 END)/60) AS minuts, COUNT(CASE WHEN CDR_GLOBAL.calldate >= '2020-05-01 00:00:00' THEN CDR_GLOBAL.id ELSE null END) AS calls FROM ICALL.CDR_GLOBAL LEFT JOIN ICALL.TRUECALLER ON TRUECALLER.phone=CDR_GLOBAL.src WHERE did IN(07212345678,07212345679) GROUP BY CDR_GLOBAL.src HAVING lastCall >= '2020-05-01 00:00:00' ORDER BY calls DESC
האם זה תקין בכלל, (אם לא אשמח ללמוד למה לא) ובמידה וכן האם יש לזה ביצועים יותר טובים?
-
@שואף מה פירוש ההצבעה?
נראה לי לפרש כך: "יפה שנזכרת בי עכשיו... כבר עברתי לנושאים אחרים ואין לי כח לחזור לזה שוב..."
טוב, אני מבין.
האמת שלא ניסיתי לעזור לך אלא לעצמי כי אני מתחיל גמור ב-SQL ואני מנסה להשתפשף.
אשמח אם יש לך כח להעיר על הקוד בין לטוב בין למוטב. -
@dovid אמר בשאילתת SQL חצויה:
טוב, אז אתה יכול לשכוח מהפתרון של window functions.
סוף סוף למדתי פחות או יותר מה זה window function.
לשם לימוד, האם המימוש על ידי window function ייראה כך?SELECT CONCAT('="', CDR_GLOBAL.src, '"') AS phone, TRUECALLER.name AS name, MIN(CDR_GLOBAL.calldate) AS firstCall, MAX(CDR_GLOBAL.calldate) AS lastCall, ROUND(SUM(CDR_GLOBAL.billsec/60) FILTER (WHERE lastCall >= '2020-05-01 00:00:00') OVER () AS minuts, COUNT(CDR_GLOBAL.id) FILTER (WHERE lastCall >= '2020-05-01 00:00:00') OVER () AS calls FROM ICALL.CDR_GLOBAL LEFT JOIN ICALL.TRUECALLER ON TRUECALLER.phone=CDR_GLOBAL.src WHERE did IN(07212345678,07212345679) GROUP BY CDR_GLOBAL.src HAVING lastCall >= '2020-05-01 00:00:00' ORDER BY calls DESC