I have a table, Messages, which is set out as follows:
This table stores all messages sent between people, however it needs to be like FaceBook's message system.
To do this my query would need to be something like:
SELECT * FROM Messages WHERE To_User = x OR From_User = x ORDER BY Time DESC
This would fetch me every message 'x' either sent or received in order of time, newest ones appearing first.
However Facebook's system keeps it sort of like a forum, so I only want one message where person y is involved in any given query result. So I don't want this to happen:
To_User: 6
From_User: 7
Status: I agree with your message
Time: 12345
To_User: 7
To_User: 6
Status: Do you agree with my message?
Time: 12344
Say I was displaying the messages page for user 6, both messages would show up with my current system.
Instead, only the top one should be selected, because I only want to display the most recent message between user 6 and 7, rather than every one.
Naturally this would usually just ask for a LIMIT statement but I need to be able to get a lot of messages, but the only rule is that:
1- It needs to be either FROM or TO user X
2- No two messages must be selected which are FROM or TO user Y
3- The messages selected must be the NEWEST in the conversation between user X and Y
This is really hard to describe but I hope I've described it in enough detail for a solution.
I've considered doing GROUP BY but I couldn't get it to take into account that it needed to find one that was either FROM or TO me rather than just only to or only from.
If the question isn't described in enough detail, please tell me before down-voting and I'll do my best to make it a bit more detailed, but I can't think of words to describe what needs to be displayed clearly enough.
Edit:
Here's a big example of the desired feature:
Say I sent a message to John Doe, and went on my messages page straight after, at the very top it'll say
"To John Doe"
"The message I sent"
However if John Doe replies, that entry will not display on the page anymore, it'll be replaced by the newest entry in the conversation between me and John Doe, so while the actual entry is still in the database, it isn't shown anymore:
"From John Doe"
"Your message is interesting"
But if I sent one to Jane Doe afterwards, it'd push me and John Doe's conversation so it looks like this:
"To Jane Doe"
"Hello there"
"From John Doe"
"Your message is interesting"
Now with the first query I stated in this post, the result would be:
"To Jane Doe"
"Hello there"
"From John Doe"
"Your message is interesting"
"To John Doe"
"The Message I sent"
However I don't want to display more than one which is between me and John Doe, but since I'm looking at two different columns in the table (From and two) to dictate whether both I and John Doe are related, I don't think a regular GROUP BY statement would work.
Now, if in addition, Bob Joe sent me a message, it might look like:
"From Bob Joe"
"Hello"
"To Jane Doe"
"Hello there"
"From John Doe"
"Your message is interesting"
You can self-join the table and use an outer join, so that any "earlier" messages will "filter out" any "non-earlier" messages.
SELECT * FROM Messages main LEFT JOIN Messages earlier
ON earlier.time < main.time AND
(
earlier.To_User = main.To_User AND earlier.From_User = main.From_User OR
earlier.To_User = main.From_User AND earlier.From_User = main.To_User
)
WHERE (main.To_User = x OR main.From_User = x) AND earlier.id IS NULL
ORDER BY main.Time DESC
If you could eliminate the complication of a person appearing in either the "from" or "to" columns, then this would be an instance of the common problem of finding the minimum row within a group. So you could start with this:
SELECT id, time, to_user as user
UNION ALL SELECT id, time, from_user as user
and then use the results of that query as the input to any of the standard minimum row techniques.
Related
I just started working at a new company and I thought that I'd make a spreadsheet for my personal use. My boss came across me working on that spreadsheet and loved it so far. They've been manually entering values into their own spreadsheets since they've started and I thought it was super tedious, so I've been working on my own for the last week trying to improve efficiency on my end. Now my bosses want me to do this for the other branches... so the pressure is real for me. I've completed every other feature they've requested, but I'm struggling with this last one so I'm here now requesting help.
I have two sheets. One called "Inspection Results" and "Still Hasn't Passed Inspection."
"Inspection Results" looks something like this:
Timestamp
Date
Name
MS Number
Address
Jurisdiction
Inspection Result
4/21/2021
4/21/2021
John Smith
MS12345
123 Test St
Orange
Passed
4/20/2021
4/20/2021
John Smith
MS12345
123 Test St
Orange
Failed
4/21/2021
4/21/2021
Rick Grimes
MS12356
123 Meme St
Riverside
Passed
4/19/2021
4/19/2021
Michelle Obama
MS54321
123 Demo St
Long Beach
Failed
4/18/2021
4/18/2021
Michelle Obama
MS54321
123 Demo St
Long Beach
Failed
4/18/2021
4/18/2021
Courage Dog
MS98765
123 Coward St
Orange
Cancelled
"Still Hasn't Passed Inspection" currently looks like this:
Name
MS Number
I want to search every row in "Inspection Results" and find the Names(Column C) of the people that do not have a inspection result(Column G) of "Passed" and write a new row in "Still Hasn't Passed Inspection" with the Name(Column C) and MS Number(Column D) of those people that could not be found with a "Passed" inspection result.
I want the table in "Still Hasn't Passed Inspection" to have unique rows. For example, there are some rows in "Inspection Results" that I have the same Name and Inspection Result. In the table that I posted, Michelle Obama failed inspection. I only want Michelle Obama to appear one time in the "Still Hasn't Passed Inspection" sheet. John Smith failed inspection one day, but passed on the following day so he wouldn't be included in the table.
Basically, based on the example table I posted above, I want "Still Hasn't Passed Inspection" to look like this:
Name
MS Number
Michelle Obama
MS54321
Courage Dog
MS98765
I'm trying to automate this process so I, or whoever, doesn't have to keep manually entering and deleting rows every time someone finally passes inspection. If someone submits a "Passed" entry into "Inspection Results" for someone that previously "Failed" or "Cancelled", I want "Still Hasn't Passed Inspection" to be updated.
Is there a way I can accomplish this with certain formulas or am I going to have to create a script on this and, if so, does anyone have a reference they can point me towards? I'm not an experienced coder. I'm not familiar with Javascript and its syntax, but I do know how variables, if statements, and for loops work. I'm not asking anyone to write me a bunch of code on this. This isn't your responsibility. If you want to, of course, it would always be appreciated. Any hints or reference towards resolving this would be amazing.
Thank you.
I am a big fan of the query (QUERY(data, query, [headers])) function. Using it, you could do something like this on "Still Hasn't Passed Inspection"
=query(Inspection Results!A2:G, "Select C, D where G = 'Failed' OR G = 'Cancelled'")
This is saying to look at the data in the Inspection Results sheet, column A2 through G (specifying no row number will go to the end of the sheet).
It is then grabbing the contents of column C and column D in Inspection Results and pulling those into the sheet with the query function, in separate columns, a row for each result. It will only pull in the results where column G (Inspection Results in your example) is the string "Failed".
You would then need a query to get the ones that have passed, and filter the resultset based on that, such as:
=filter(query(A2:G, "Select C, D where G = 'Failed' OR G = 'Cancelled'"), arrayformula(not(countif(query(A2:G, "Select D where G = 'Passed'"), query(A2:G, "Select D where G = 'Failed' OR G = 'Cancelled'")))))
This is essentially saying, "Filter my query of not-passed inspections by looking at passed inspections, and not including any with the same MS Number"
I would like to get the messages that someone hasnt read... it could be a count o just a "1" if there are pending messages to read.
The trick is that there are many " users" shareing the same system. So if I usear "A" reads a message from the table then the notification wont appear anymore to A, but for "B" there should be a notification of pending messages. They are sharing the same message lets say.
I create a query that works somehow , but I know is not 100% right.
I did review
Querying conversations from messages table
sql messages table query
In the example below is the deal.
"A" last viewbymessage for the docid 93 was on 2019-01-28 10:02:15, then user B send a new message BUT never reads the message sent by "A", so in my query, "A" will never be able to see there was a new message since he was the last to see if, and I not using the MessageTable only the Messages_View .. I know this is the wrong part, but im just stating how I used to have it.
SELECT B.*
FROM Comments_Viewed_Tbl B LEFT JOIN Comments_Viewed_Tbl C
ON (B.DOCID =C.DOCID and B.Date_Viewed < C.Date_Viewed)
WHERE C.Date_Viewed IS NULL and B.viewedby <>'A' and
B.RPDOC = 93 and B.Country ='USA'
*sorry for the image, I did try to put it as text but the system format irt ugly
How would be the best approach to do the query.
In this scenario A should have an alert or counter of the new message as also B since he/she didnt check it and just send a new one.
So adding a comment is the same as sending a message?
From my point of view, you need to add the CommentID column to the Comments_Viewed_Tbl, otherwise you will never be able to see the read status of each specific comment, only for the whole document.
Otherwise you will need to assume that the last person to add a comment to the document has read all previous comments.
I'm working on a school database on which I would like to implement messages that will be created by the schools for the parents to view.
The workflow goes like this:
1. The school sends a message to a certain group of students, it could be a message to all the students from that school, or a message to just the first year, or a message to classroom 1B (1 being the year and B the group), or even a message to just 1 student.
2. Parents access a platform on which they will see the messages regarding their children.
For example:
if the school sends a message to the classroom 1B, only parents with children on that classroom will be able to see it.
if the school sends a message to the first year, only parents with
children on the first year will see it.
What I need help with is:
How could I arrange the database in order to accomplish the message
filtering (By school, by year, by classroom (1B, 2A,
etc.) and by student)?
What would be the sentence that I need to use in order to retrieve
the messages for a parent regarding their children?
I hope I explained myself well, please feel free to ask any question you have, and thank you so much :)
Here's a pic of the database:
If I understood well, for this question "What would be the sentence that I need to use in order to retrieve the messages for a parent regarding their children?" you could use a simple inner join between message and parent_detail on id_students are equals where id_parent is your parentID:
SELECT * FROM `message` m
INNER JOIN `parent_detail` p_d on p_d.ID_student = m.ID_student
WHERE p_d.ID_detail = 'parent_id_variable'
Regarding the first question, using the same principle, you need to use an inner join between message students and schools (if you want the name of the school and not only the ID) and apply in where condition what parameter you want.
For example, by school => message.ID_school, by school and by year => message.ID_school and students.year.
I have a very big problem with my website. I have a form, more like a text box used in submitting comments, that not the problem. The problem is displaying the comments. I want to display comments based on the friends a user added like the way facebook, twitter does.
I have 3 tables:photo_tb, comment_tb, friendship_tb.
The friendship_tb contains columns name, friend. name stores your email and friend stores the email of the person you add....
I need the photo_tb to get the picture of the person making the comment and I use a mysql join successfully.
In my comment_tb...i get the email of the person making the comment in my commentname column and comment made by the person...
I want to to show comment by ffriendship like if Mr A adds Mr B and Mr c..when Mr A logs on he should only get comments by both Mr B and Mr c and his comments doe not comments from Mr G or H.
This is what i have so far
SELECT
comment_tb.comment_id
, comment_tb.comname
, comment_tb.comment
, comment_tb.time
, photo_tb.name
, photo_tb.photo
, friendship.name
, friendship.member
FROM comment_tb, photo_tb, friendship
WHERE
comment_tb.comname=photo_tb.name
and friendship.name = colname
The colname is a variable for MM_Username ,the session variable when you log in is meant to display comments related to you.
The sql statement attaches the picture to each comment name successfully but doesn't limit the comment to friends added.
Add and friendship.member = comment_tb.comname.
BTW, it would be nice if the column names in your SQL matches what you said in the description. I'm just guessing that friendship.member is what you called friend in the text.
Wow, makes your head spin!
I am about to start a project, and although my mySql is OK, I can't get my head around what required for this:
I have a table of web addresses.
id,url
1,http://www.url1.com
2,http://www.url2.com
3,http://www.url3.com
4,http://www.url4.com
I have a table of users.
id,name
1,fred bloggs
2,john bloggs
3,amy bloggs
I have a table of categories.
id,name
1,science
2,tech
3,adult
4,stackoverflow
I have a table of categories the user likes as numerical ref relating to the category unique ref. For example:
user,category
1,4
1,6
1,7
1,10
2,3
2,4
3,5
.
.
.
I have a table of scores relating to each website address. When a user visits one of these sites and says they like it, it's stored like so:
url_ref,category
4,2
4,3
4,6
4,2
4,3
5,2
5,3
.
.
.
So based on the above data, URL 4 would score (in it's own right) as follows: 2=2 3=2 6=1
What I was hoping to do was pick out a random URL from over 2,000,000 records based on the current users interests.
So if the logged in user likes categories 1,2,3 then I would like to ORDER BY a score generated based on their interest.
If the logged in user likes categories 2 3 and 6 then the total score would be 5. However, if the current logged in user only like categories 2 and 6, the URL score would be 3. So the order by would be in context of the logged in users interests.
Think of stumbleupon.
I was thinking of using a set of VIEWS to help with sub queries.
I'm guessing that all 2,000,000 records will need to be looked at and based on the id of the url it will look to see what scores it has based on each selected category of the current user.
So we need to know the user ID and this gets passed into the query as a constant from the start.
Ain't got a clue!
Chris Denman
What I was hoping to do was pick out a random URL from over 2,000,000 records based on the current users interests.
This screams for predictive modeling, something you probably wouldn't be able to pull off in the database. Basically, you'd want to precalculate your score for a given interest (or more likely set of interests) / URL combination, and then query based on the precalculated values. You'd most likely be best off doing this in application code somewhere.
Since you're trying to guess whether a user will like or dislike a link based on what you know about them, Bayes seems like a good starting point (sorry for the wikipedia link, but without knowing your programming language this is probably the best place to start): Naive Bayes Classifier
edit
The basic idea here is that you continually run your precalculation process, and once you have enough data you can try to distill it to a simple formula that you can use in your query. As you collect more data, you continue to run the precalculation process and use the expanded results to refine your formula. This gets really interesting if you have the means to suggest a link, then find out whether the user liked it or not, as you can use this feedback loop really improve the prediction algorithm (have a read on machine learning, particularly genetic algorithms, for more on this)
I did this in the end:
$dbh = new NewSys::mySqlAccess("xxxxxxxxxx","xxxxxxxxxx","xxxxxxxxx","localhost");
$icat{1}='animals pets';
$icat{2}='gadget addict';
$icat{3}='games online play';
$icat{4}='painting art';
$icat{5}='graphic designer design';
$icat{6}='philosophy';
$icat{7}='strange unusual bizarre';
$icat{8}='health fitness';
$icat{9}='photography photographer';
$icat{10}='reading books';
$icat{11}='humour humor comedy comedian funny';
$icat{12}='psychology psychologist';
$icat{13}='cartoons cartoonist';
$icat{14}='internet technology';
$icat{15}='science scientist';
$icat{16}='clothing fashion';
$icat{17}='movies movie latest';
$icat{18}="\"self improvement\"";
$icat{19}='drawing art';
$icat{20}='latest band member';
$icat{21}='shop prices';
$icat{22}='recipe recipes food';
$icat{23}='mythology';
$icat{24}='holiday resorts destinations';
$icat{25}="(rude words)";
$icat{26}="www website";
$dbh->Sql("DELETE FROM precalc WHERE member = '$fdat{cred_id}'");
$dbh->Sql("SELECT * FROM prefs WHERE member = '$fdat{cred_id}'");
#chos=();
while($dbh->FetchRow()){
$cat=$dbh->Data('category');
$cats{$cat}='#';
}
foreach $cat (keys %cats){
push #chos,"\'$cat\'";
push #strings,$icat{$cat};
}
$sqll=join("\,",#chos);
$words=join(" ",#strings);
$dbh->Sql("select users.id,users.url,IFNULL((select sum(scoretot.scr) from scoretot where scoretot.id = users.id and scoretot.category IN \($sqll\)),0) as score from users WHERE MATCH (description,lasttweet) AGAINST ('$words' IN BOOLEAN MODE) AND IFNULL((SELECT ref FROM visited WHERE member = '$fdat{cred_id}' AND user = users.id LIMIT 1),0) = 0 ORDER BY score DESC limit 30");
$cnt=0;
while($dbh->FetchRow()){
$id=$dbh->Data('id');
$url=$dbh->Data('url');
$score=$dbh->Data('score');
$dbh2->Sql("INSERT INTO precalc (member,user,url,score) VALUES ('$fdat{cred_id}','$id','$url','$score')");
$cnt++;
}
I came up with this answer about three months ago, and just cannot read it. So sorry, I can't explain how it finally worked, but it managed to query 2 million websites and choose one based on the history of a users past votes on other sites.
Once I got it working, I moved on to another problem!
http://www.staggerupon.com is where it all happens!
Chris