retrieving information from 3 tables - mysql

I have three tables:
users:
+----------+-----------------------------+-----------+
| users_id | user detail | otherID |
+----------+-----------------------------+-----------+
| 1 | user name or details | 1 |
| 2 | user name or details | 1 |
| 3 | user name or details | 4 |
| 4 | user name or details | 1 |
| 5 | user name or details | 21 |
| 6 | user name or details | 2 |
+----------+-----------------------------+-----------+
photos:
+----------+----------------+-----------+--------+---------+--------------+
| photosID | url | title | userID | likes | remarksID |
+----------+----------------+-----------+--------+---------+--------------+
| 1 | 7459.JPG | TITLE | 1 | 150 | 255 |
| 2 | 7510.JPG | TITLE | 1 | 146 | 247 |
| 3 | 7460.JPG | TITLE | 2 | 2 | 56 |
+----------+----------------+-----------+--------+---------+--------------+
remarks:
+-----------+---------------------------------------+---------+------------+
| remarksID | remark | userID | photoID |
+-----------+---------------------------------------+---------+------------+
| 1 | REMARKS for PhotoID 1 | 1 | 1 |
| 2 | REMARKS for PhotoID 1 | 1 | 1 |
| 3 | REMARKS for PhotoID 1 | 1 | 1 |
| 4 | REMARKS for PhotoID 2 | 1 | 2 |
| 5 | REMARKS for PhotoID 2 | 1 | 2 |
| 6 | REMARKS for PhotoID 3 | 2 | 3 |
+-----------+---------------------------------------+---------+------------+
I am trying to extract the remarks for a given users photo, but only want the photo to appear once but all the relevant remarks for the photo to be displayed for each users photo.
If there are no remarks then just display the photo without remarks.
The layout would look like this on a web page-
------------------------------------
Photograph 1
Remarks 1
Remarks 2
Remarks 1
------------------------------------
Photograph 2
NO remarks for photo
------------------------------------
Photograph 3
Remarks 1
Remarks 2
Remarks 3
Remarks 4
------------------------------------
Photograph 4
Remarks 1
Remarks 2
------------------------------------

Is my assumption correct that your difficulty is, how to get the database to do this? If so, then the answer is that this function (formatting the data), is not (or should not) generally be the responsibility of the database. Fetch the photos from the database as one result set, then fetch the matching comments in another, and let your application or reporting tool format the data the way you want it.

Related

How can I list the 5 most followed stocks in sql?

I have a tracking table, the content of the tracking table contains products. I want to list the most followed products with procedure How can I do this?
Follow-up chart
| ID |KullaniciID| StokKodu | Tarih |
| 1 | 1 | AXERA | 2023-02-01 15:10:53.193 |
| 2 | 1 | ERKMF | 2023-02-02 10:27:17.373 |
| 3 | 2 | AXERA | 2023-02-02 10:27:16.643 |
| 4 | 3 | AXERA | 2023-02-06 16:27:28.873 |
In this table given as an example, I want to list 5 of the most followed products according to the stock code, how do I do this?

Grab unique data from repeating record

I've got a procedural question that is likely going to expose how burnt out I am. I have 3 tables, users, projects and project_users. projects is joined with project_user to allow users to share projects.
I'd like to let, say, Bob see all of his projects and who he is sharing them with. In the example below Bob's sharing his 1 project with everyone. In his dashboard I'd like to show him "Bob's 1 Project" with everyone it's shared with. This is being managed in a while loop because Bob really has dozens of projects he's sharing with dozen's of people. The problem is, how can I show 1 project with everyone it's shared_with instead of showing the same project over and over each time there's a new shared_with value?
id | users | | id | projects | | id | owner_id | shared_with | project_id | role
---+-------------------- ---+------------------- ---+----------+-------------+------------+------
1 | bob#here.com | | 1 | Bob's 1 Project | | 1 | 1 | NULL | 1 | 1
2 | tom#there.com | | 2 | Tom's | | 2 | 1 | 4 | 1 | 2
3 | jan#red.com | | 3 | Jan's | | 3 | 1 | 2 | 1 | 2
4 | joe#somewhere.com | | 4 | Joe's Project | | 4 | 1 | 3 | 1 | 2
5 | fred#where.com | | 5 | Fred's Project | | 5 | 1 | 5 | 1 | 2

Storing changes on MySQL Database properly

I've currently got three tables to track changes on specific entries but it seems like I am ending up with a ton of entries and I am not sure if that is the best possible way.
My first table holds the basic information and the second and third one the extra entries I grab every 8 hours.
ID | creation_date | removal_date | article_url | status which are basically the most stable entries. Status and removal_date are the only ones that will change in case we disable/remove an entry.
Example:
ID | creation_date | removal_date | article_url | status
---|------------------|------------------|-------------|-------
1 | 10/01/2020 20:00 | NULL | http://xxx | 1
2 | 23/01/2020 10:00 | 27/01/2020 13:00 | http://xxx2 | 2
3 | 10/02/2020 15:00 | NULL | http://xxx3 | 1
Status 1 = Active
Status 2 = Inactive
The second table holds everything else:
ID | main_id | last_update | title | description | views | rating | comments
The second table creates a new entry every 8 hours as long as something changes. Then based on the entries added here, I show average views/rating/comments changes on a daily/weekly/monthly basis.
Example:
ID | main_id | last_update | title | description | views | rating | comments
---|---------|------------------|----------------|--------------------|-------|--------|---------
1 | 1 | 10/01/2020 20:00 | First Article | Description.. | 1 | 1 | 0
2 | 2 | 23/01/2020 10:00 | Second Article | Desc.. | 1 | 1 | 0
3 | 1 | 11/01/2020 20:00 | First Article | Description update | 15 | 3 | 2
4 | 1 | 12/01/2020 20:00 | 1st Article | Description update | 30 | 5 | 4
5 | 3 | 10/02/2020 15:00 | 3rd Article | Descript! | 3 | 1 | 1
The third table holds the tags:
ID | main_id | tag_id | date_added | date_removed
I thought instead of having a status to add an empty date_removed so in case the tags get updated/removed/etc update that part. The tags are saved in a separate table and just grab the id and store the connection between the two here.
Example:
ID | main_id | tag_id | date_added | date_removed
---|---------|--------|------------------|------------------
1 | 1 | 2 | 10/01/2020 20:00 | NULL
2 | 1 | 3 | 15/01/2020 16:30 | 17/01/2020 13:00
3 | 2 | 3 | 23/01/2020 10:00 | NULL
4 | 3 | 5 | 10/02/2020 15:00 | NULL
5 | 1 | 5 | 11/02/2020 17:00 | NULL
I'd just like to know if there is a better / more proper way to store the above data.
Yepp, #Maria, is clearer.
Assuming that you are dealing with blog entries, you may have a data model like this.
Table 1. articles. // where every article is created.
article_id | article_creation_date | article_title | article_url | article_creator_id | article_description |
-----------|-----------------------|---------------|-------------|--------------------|------------------------------|
1 | 2020/03-31 10:36:05 | "The Dilemma" | /articles/1 | 23 | Explains the relations....|
Table 2. article_status // stores changes of state to each article.
article_status | article_id | status | date_of_change |
---------------|------------|--------|--------------------|
1 | 1 | 7 | 15/04/2020 09:30:00|
Table 3. article_tags. // every article and it's tags
article_tag | article_id | tag_id | date_added |
------------|------------|--------|--------------------|
1 | 1 | 24 | 15/04/2020 09:30:00|
Table 4. article views // stores the summarized amount of views to each article, for a period, say day, week, 8 hours,...
article_v_id | article_id | views_summarized | time_lapse | time_lapse_value | date_summarization |
-------------|------------|------------------|----------------|-------------------|-------------------|
1 | 1 | 1578 | Day | 10/04/2020 | 12/04/2020 13:27:04 |
Table 5. article_updates // stores changes/updates made to each article.
article_update_id | article_id | type_of_update | update_detail | update_author | date_of_update |
------------------|------------|--------------------------------|---------------|------------------------|
1 | 1 | Title | | John Doe | 19/04/2020 15:27:24 |
And the contentn of the update is stored directly on articles table, say change of title. NO need to store all modified titles, content. Just the event and who made the change.

How to select every level with different user and user progress

I wanted to make a learning apps with a completed questions progress track on each level. I have 2 tables which contain all the level with its question count, and a table that save an user progress (completed questions) on each level. Here is the record,
Level table:
+----------+----------------------+-------------+--------+
| id_level | name | jumlah_soal | id_sub |
+----------+----------------------+-------------+--------+
| 1 | Basic Level 1 | 5 | 1 |
| 2 | Basic Level 2 | 6 | 1 |
| 3 | Basic Level 3 | 7 | 1 |
| 8 | Intermediate Level 1 | 5 | 2 |
| 9 | Intermediate Level 2 | 5 | 2 |
| 10 | Intermediate Level 3 | 5 | 2 |
..........................................................
Progress Table:
+-----------------+---------+-------------+----------+
| id_progreslevel | id_user | completed | id_level |
+-----------------+---------+-------------+----------+
| 1 | 1 | 2 | 1 |
| 2 | 1 | 3 | 2 |
| 3 | 2 | 2 | 1 |
+-----------------+---------+-------------+----------+
and when I joined the tables with the following query
SELECT IFNULL(progreslevel.id_user, 1) as id_user,
-> level.*, IFNULL(progreslevel.completed, 0) as completedquestions
-> FROM level LEFT JOIN progreslevel
-> ON level.id_level = progreslevel.id_level
-> WHERE level.id_sub = 1
-> HAVING id_user = 1;
It queries what I wanted:
+---------+----------+---------------+-------------+--------+--------------------+
| id_user | id_level | name | jumlah_soal | id_sub | completed questions |
+---------+----------+---------------+-------------+--------+--------------------+
| 1 | 1 | Basic Level 1 | 5 | 1 | 2 |
| 1 | 2 | Basic Level 2 | 6 | 1 | 3 |
| 1 | 3 | Basic Level 3 | 7 | 1 | 0 |
+---------+----------+---------------+-------------+--------+--------------------+
BUT, when I tried to change to query a progress for user ID = 2, it became like this:
+---------+----------+---------------+-------------+--------+--------------------+
| id_user | id_level | name | jumlah_soal | id_sub | completed questions |
+---------+----------+---------------+-------------+--------+--------------------+
| 2 | 1 | Basic Level 1 | 5 | 1 | 2 |
| 2 | 3 | Basic Level 3 | 7 | 1 | 0 |
+---------+----------+---------------+-------------+--------+--------------------+
Yes, the Basic Level 2 is gone because user 2 hadn't done it yet but user 1 had.
This is where I'm stuck, I want to whichever user I choose, its always query all the level, even when the other user had done it. It should be like this:
+---------+----------+---------------+-------------+--------+--------------------+
| id_user | id_level | name | jumlah_soal | id_sub | completed questions |
+---------+----------+---------------+-------------+--------+--------------------+
| 2 | 1 | Basic Level 1 | 5 | 1 | 2 |
| 2 | 2 | Basic Level 2 | 6 | 1 | 0 |
| 2 | 3 | Basic Level 3 | 7 | 1 | 0 |
+---------+----------+---------------+-------------+--------+--------------------+
How do I achieve this?
Thanks in advance and Sorry if you got dizzy either at my explanation or database, I tried my best to translate it, so it's understandable
I'm not really sure that I understand the requirement, but I think you're after something like this...
SELECT l.*
, 2 id_user
, COALESCE(MAX(p.completed),0) completed_questions
FROM level l
LEFT
JOIN progress p
ON p.id_level = l.id_level
AND p.id_user = 2
WHERE l.id_sub = 1
GROUP
BY l.id_level;

Normalisation of product/protocol review system

I'm working on a review system, where reviews for products are shown based on the outcome of a questionnaire.
Example:
What food do you like (Italian, French or fusion)
Which vegetables do you like (spinach, tomato or broccoli)
How much money would you like to spend on dinner ($0-$10, $11-$20 or $21-$30)
If someone selects Italian, tomato, $0-$10, then the user would see (for example) 20 types of pizza's, with reviews from other users shown.
But we only want to show products that have been reviewed for the exact same outcome of the questionnaire (we call this the protocol).
Table: questions
-----------------------------------
| id | question |
-----------------------------------
| 1 | What food do you like |
-----------------------------------
| 2 | Which vegetables do you... |
-----------------------------------
Table: possible_answers
-----------------------------------
| id | question_id | answer |
-----------------------------------
| 1 | 1 | Italian |
-----------------------------------
| 2 | 1 | French |
-----------------------------------
Table: products
---------------------
| id | product |
---------------------
| 1 | Pizza Salami |
---------------------
| 2 | Pizza cheese |
---------------------
From a database perspective (we're using mySQL), I'm wondering how to store the protocol attached to each review
[OPTION 1]
Table: reviews
---------------------------------------------------------------------------
| id | product_id | answer_q1_id | answer_q2_id | answer_q3_id | rating |
---------------------------------------------------------------------------
| 1 | 2 | 3 | 57 | 166 | 4 |
---------------------------------------------------------------------------
| 2 | 25 | 3 | 57 | 166 | 5 |
---------------------------------------------------------------------------
[/OPTION 1]
[OPTION 2]
Table: reviews
-------------------------------
| id | product_id | rating |
-------------------------------
| 1 | 2 | 4 |
-------------------------------
| 2 | 25 | 5 |
-------------------------------
Table: protocol
-----------------------------------------------
| id | review_id | question_id | answer_id |
-----------------------------------------------
| 1 | 1 | 1 | 3 |
-----------------------------------------------
| 2 | 1 | 2 | 57 |
-----------------------------------------------
| 2 | 1 | 3 | 166 |
-----------------------------------------------
[/OPTION 2]
Normally, I'd go with option 2 which just 'feels' better. But I'm not sure how one could query the protocol table to get all product reviews for a specific path in the questionnaire (protocol). For example when the user answers 'italian, spinach, 0-10', how do I find out which product reviews go with that combination of answers using option 2 (with option 1 it is obvious how to do this)?
I hope I've explained this well and I'm looking forward to reading thoughts from the community.
Greatly appreciated,
Lionel.