| Version 5 (modified by , 7 days ago) ( diff ) |
|---|
Nutritioneer | Напредни извештаи од базата
| Ознака | Операција |
|---|---|
| σ | |
| π | |
| ⋈ | |
| ⟕ | |
| γ | |
| τ | |
| − | |
| ω | |
| ← | |
| SUM(x | у) |
Извештај 1: Преглед на активноста во заедницата
Account Activity Log
Опис на барањата за податоци
Извештајот покажува колку е активна секоја сметка во четирите дела на апликацијата. За секој корисник ги брои креираните рецепти, објавите, коментарите и записите во дневникот, заедно со неговата улога од USER кон RECIPE, POST, COMMENT и INTAKE_PLANNER.
SQL - приказ
SELECT u.username,
u.role,
COUNT(DISTINCT r.id) AS recipes_created,
COUNT(DISTINCT p.id) AS posts_created,
COUNT(DISTINCT c.id) AS comments_written,
COUNT(DISTINCT ip.id) AS diary_entries
FROM "user" u
LEFT JOIN recipe r ON r.user_id = u.id
LEFT JOIN post p ON p.user_id = u.id
LEFT JOIN comment c ON c.user_id = u.id
LEFT JOIN intake_planner ip ON ip.user_id = u.id
GROUP BY u.id, u.username, u.role
ORDER BY recipes_created DESC, posts_created DESC, u.username;
Релациона алгебра - приказ
τ_{recipes_created DESC, posts_created DESC, username} (
γ_{u.id, u.username, u.role;
COUNT(DISTINCT r.id) → recipes_created,
COUNT(DISTINCT p.id) → posts_created,
COUNT(DISTINCT c.id) → comments_written,
COUNT(DISTINCT ip.id) → diary_entries} (
User ⟕_{u.id = r.user_id} Recipe
⟕_{u.id = p.user_id} Post
⟕_{u.id = c.user_id} Comment
⟕_{u.id = ip.user_id} Intake_Planner
)
)
Извештај 2: Профил на макронутриенти по порција
Health Stat Check
Опис на барањата за податоци
Протеини, јаглехидрати, масти и влакна во една порција од секој рецепт. Спојува две одделни M:N врски во еден нутритивен приказ: рецепт содржи состојки, а состојка содржи нутриенти. За секој рецепт пресметува колку грама од секој макронутриент дава една порција, и ги рангира рецептите по протеини.
- (нутриент на 100 g) × (употребени грамови) / 100 преку сите состојки, поделен со бројот на порции.
SQL - приказ
SELECT r.name AS recipe,
ROUND(r.kcal_sum / r.servings) AS kcal_per_portion,
ROUND(SUM(CASE WHEN n.description = 'Protein'
THEN icn.quantity * rci.ingredient_quantity / 100
END) / r.servings, 1) AS protein_g,
ROUND(SUM(CASE WHEN n.description = 'Total carbohydrate'
THEN icn.quantity * rci.ingredient_quantity / 100
END) / r.servings, 1) AS carbs_g,
ROUND(SUM(CASE WHEN n.description = 'Total fat'
THEN icn.quantity * rci.ingredient_quantity / 100
END) / r.servings, 1) AS fat_g,
ROUND(SUM(CASE WHEN n.description = 'Dietary fibre'
THEN icn.quantity * rci.ingredient_quantity / 100
END) / r.servings, 1) AS fibre_g
FROM recipe r
JOIN recipe_contains_ingredient rci ON rci.recipe_id = r.id
JOIN ingredient_contains_nutrient icn ON icn.ingredient_id = rci.ingredient_id
JOIN nutrient n ON n.id = icn.nutrient_id
WHERE n.type = 'macro'
GROUP BY r.id, r.name, r.kcal_sum, r.servings
ORDER BY protein_g DESC;
Релациона алгебра - приказ
amount ≡ icn.quantity · rci.ingredient_quantity / 100
τ_{protein_g DESC} (
γ_{r.id, r.name, r.kcal_sum, r.servings;
SUM(amount | n.description = 'Protein') / r.servings → protein_g,
SUM(amount | n.description = 'Total carbohydrate') / r.servings → carbs_g,
SUM(amount | n.description = 'Total fat') / r.servings → fat_g,
SUM(amount | n.description = 'Dietary fibre') / r.servings → fibre_g} (
σ_{n.type = 'macro'} (
Recipe
⋈_{r.id = rci.recipe_id} Recipe_Contains_Ingredient
⋈_{rci.ingredient_id = icn.ingredient_id} Ingredient_Contains_Nutrient
⋈_{icn.nutrient_id = n.id} Nutrient
)
)
)
Извештај 3: Ден со најголем внес по корисник
Callorie-maxing view
Опис на барањата за податоци
Фокус на денот со најмногу калории на секој корисник наспроти неговиот сопствен просек. секој корисник што води дневник на исхрана, извештајот го наоѓа денот во кој внел најмногу енергија. Тој ден го споредува со просечниот дневен внес на истиот корисник.
- RANK() ги дели деновите по корисник и ги подредува по енергија
- AVG() врз истата партиција го дава просекот.
ROW_NUMBER() прикажуваше само една инстанца ако имаше дупликати/денови со ист број калории
SQL - приказ
WITH daily_intake AS (
SELECT u.username,
ip.date_time::date AS intake_day,
SUM(ip.kcal) AS kcal_consumed,
COUNT(*) AS meals_logged,
ROUND(AVG(SUM(ip.kcal)) OVER (PARTITION BY u.id)) AS avg_daily_kcal,
RANK() OVER (PARTITION BY u.id ORDER BY SUM(ip.kcal) DESC) AS day_rank
FROM "user" u
JOIN intake_planner ip ON ip.user_id = u.id
WHERE ip.is_consumed = TRUE
GROUP BY u.id, u.username, ip.date_time::date
)
SELECT username, intake_day, kcal_consumed, meals_logged, avg_daily_kcal
FROM daily_intake
WHERE day_rank = 1
ORDER BY kcal_consumed DESC;
Релациона алгебра - приказ
Daily ← γ_{u.id, u.username, date(ip.date_time) → intake_day;
SUM(ip.kcal) → kcal_consumed, COUNT(*) → meals_logged} (
σ_{ip.is_consumed = TRUE} (User ⋈_{u.id = ip.user_id} Intake_Planner)
)
τ_{kcal_consumed DESC} (
π_{username, intake_day, kcal_consumed, meals_logged, avg_daily_kcal} (
σ_{day_rank = 1} (
ω_{PARTITION BY u.id;
RANK() ORDER BY kcal_consumed DESC → day_rank,
AVG(kcal_consumed) → avg_daily_kcal} (Daily)
)
)
)
Извештај 4: Целосно растителни рецепти
Go Green Filter
Опис на барањата за податоци
Рецепти чија секоја состојка е од растителна категорија, проверени наспроти веганската ознака. пронаоѓа рецептите во кои секоја состојка е од растително потекло. Тоа е релациско делење: рецептот се квалификува само ако бројот на неговите растителни состојки е еднаков на бројот на сите негови состојки. Една состојка од животинско потекло го дисквалификува целиот рецепт. Растителни се типовите:
- vegetable
- fruit
- legume
- nut
- seed
- oil
- herb
- spice
- carb
- beverage
- Медот и јајцето се од типот other -> дисквалификуваат
SQL - приказ
SELECT r.name AS recipe,
u.username AS author,
COUNT(*) AS ingredient_count,
ROUND(r.kcal_sum / r.servings) AS kcal_per_portion,
EXISTS (SELECT 1
FROM recipe_contains_restriction rcr
JOIN restriction res ON res.id = rcr.restriction_id
WHERE rcr.recipe_id = r.id
AND res.type = 'vegan') AS tagged_vegan
FROM recipe r
JOIN "user" u ON u.id = r.user_id
JOIN recipe_contains_ingredient rci ON rci.recipe_id = r.id
JOIN ingredient i ON i.id = rci.ingredient_id
WHERE i.type IN ('vegetable', 'fruit', 'legume', 'nut', 'seed',
'oil', 'herb', 'spice', 'carb', 'beverage')
GROUP BY r.id, r.name, u.username, r.kcal_sum, r.servings
HAVING COUNT(*) = (SELECT COUNT(*)
FROM recipe_contains_ingredient rci2
WHERE rci2.recipe_id = r.id)
ORDER BY kcal_per_portion;
Релациона алгебра - приказ
Plant ← {'vegetable', 'fruit', 'legume', 'nut', 'seed',
'oil', 'herb', 'spice', 'carb', 'beverage'}
AnimalUse ← π_{rci.recipe_id} (
σ_{i.type ∉ Plant} (
Recipe_Contains_Ingredient ⋈_{rci.ingredient_id = i.id} Ingredient
)
)
PlantOnly ← π_{rci.recipe_id} (Recipe_Contains_Ingredient) − AnimalUse
τ_{kcal_per_portion} (
γ_{r.id, r.name, u.username; COUNT(*) → ingredient_count} (
(PlantOnly ⋈_{recipe_id = r.id} Recipe)
⋈_{r.user_id = u.id} User
⋈_{r.id = rci.recipe_id} Recipe_Contains_Ingredient
)
)
Навигација низ проектот
| Фаза | Име на фаза | Статус |
|---|---|---|
| P0 | Дефинирање проект | Одобрен |
| P1 | Концептуален дизајн и ЕР Дијаграм | Одобрен |
| P2 | Логички и физички дизајн - DDL | Одобрен |
| P3 | Кориснички/апикациски сценарија со базата на податоци | Одобрен |
| P4 | Протип со основни функционалности | WIP |
| М1 | Презентација на прототип | WIP |
| P5 | Нормализација и оптимизација на дизајн | WIP |
| P6 | Напредни извештаи од базата | WIP |
| P7 | Понапреден развој на базата | WIP |
| P8 | Напреден апликативен развој | WIP |
| P9 | Дополнителни имплементации | WIP |
| М2 | Финализиран проект | WIP |
(Trac навигација)
- TracGuide Documentation
