@dovid כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
א. השאלה לא עסקה בknex אלא בSQL
השאלה עדיין עומדת על SQL שאלתי
כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
השאלה איך נכון לעשות את זה.
וחידדתי
כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
מבחינת עומס על השרת, AI למיניהם טענו שכ"כ הרבה join מהוה עומס על השרת ומכביד סתם על כל תהליך השליפה, מה שא"כ אם חלק מהם עושים ע"י בקשה שניה בקוד עצמו.
האמת, שאני רואה עכשיו שיצא לא מובן (בכל זאת 4 לפנות בוקר, קמתי רק להכין מטרנה או משהו...) אז אסביר כאן ואשנה גם שם.
הבעיה שלי היא לא המימוש, (כמו שכתבתי כמה וכמה פעמים, אני משתדל לא לבקש שיכתבו במקומי אלא איך נכון לעשות) אלא האם נכון לשלב 4 טבלאות ביחד... ניסיתי לחדד בהודעה השניה שהAI טענו שלא כדאי לעשות גם לזה JOIN כיון שזה מאוד מכביד על השרת, אלא עדיף למשוך את הערים בשאילתא נפרדת שלא תסבך את השרת, ושאלתי (לפחות התכוונתי) האם זה נכון? או שהם טועים ואין שום בעיה לחבר טבלאות.
@dovid כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
לראשונה בחיי שאני שומע על knex
גם אני, @צדיק-תמים המליץ לי עליה במקום אחר ושיניתי את כל הפרויקט לספריה הזו, אני חושב שהיא מאוד שימושית.
@dovid כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
אבל תבין שהשאלה הראשונה מזמינה כל אחד שקצת למד SQL לענות
מצוין, זה מה שאני צריך, כאמור אני צריך תאורטית, מה הדרך הנכונה, והאם הטענה ההיא נכונה או לא נכונה.
@dovid כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
ובהודעה האחרונה אתה דופק את כלי מי שהיה טורח לענות, כי כמה שהתשובה יפה ונכונה היא לא בטוח רלוונטית עבור איזה כלי בשם knex
לא דופק אף אחד, מותר להגיד "הדרך של חיבור 4 טבלאות היא הנכונה כאן, לגבי knex - לא יודע" (אגב, בknex אפשר גם להכניס raw כך שאין בעיה, מכניסים שאילתת SQL כמו שהיא והכל טוב).
@dovid כתב בשליפת נתונים מטבלה עם 3 טבלאות מקושרות:
בין העובדה שאתה לא יודע בכלל SQL
מי קבע? למדתי את הנושא, הבנתי פחות או יותר אני יודע מה שאני צריך, נכון אני לא יודע עד הסוף, אבל את הבסיס אני בהחלט יודע. יש כאן לדוגמא מדריך חמוד ועוד מקומות. ובינינו SQL בסיסי כמו שאני צריך זה לא משהו מורכב כ"כ.
התנאים אצלי נראים יותר ככה:
let queryBuilder = knex("advertiser_ads as M").select("M.*");
queryBuilder.leftJoin("ratings as R", "R.rated", "M.phone");
queryBuilder.select(knex.raw("AVG(R.rating) as average_rating"));
queryBuilder.groupBy("M.id");
עוד קוד, לא רלוונטי
if (filters.phoneOfSearcher && isValidIsraeliPhone(filters.phoneOfSearcher)) {
queryBuilder.select(
knex.raw(
`EXISTS (
SELECT 1 FROM advertiser_ads_read MK
WHERE MK.id = M.id AND MK.phone = ?
) as was_read`, [filters.phoneOfSearcher]
)
);
}
עוד קוד לא רלוונטי
queryBuilder.innerJoin("advertiser_cities as E", "E.id", "M.id");
queryBuilder.groupBy("M.id"); // חשוב למנוע כפילויות במודעה אם יש לה כמה ערים
if (filters.cities && filters.cities.length > 0) {
// המצב שבו המחפש הזין עיר/ערים ספציפיות
queryBuilder.where(function() {
// כלל 3: לשניהם יש עיר - בדיקת התאמה מדויקת לעיר
this.whereIn("E.city", filters.cities)
// כלל 2: למפרסם יש רק אזור - מפרסם שמשרת את כל האזור יעלה בתוצאות
.orWhere(function() {
this.where("E.area", filters.area).whereNull("E.city");
})
// כלל 1 (מתוקן ומאובטח): למפרסם יש "כל הארץ" (אזור ריק + עיר ריקה) - הוא יעלה בתוצאות תמיד
.orWhere(function() {
this.whereNull("E.area").whereNull("E.city");
});
});
} else {
// המצב שבו המחפש הזין רק אזור (ללא עיר)
queryBuilder.where(function() {
// כלל 2: חיפוש לפי אזור (מכסה מפרסמים של כל האזור, וגם מפרסמים של עיר ספציפית באזור)
this.where("E.area", filters.area)
// כלל 1 (מתוקן ומאובטח): למפרסם יש "כל הארץ" (אזור ריק + עיר ריקה) - הוא יעלה בתוצאות תמיד
.orWhere(function() {
this.whereNull("E.area").whereNull("E.city");
});
});
}
תנאים מורכבים שחושבו כמו שצריך.