简体   繁体   中英

How can I select and order rows from one table based on values contained in another?

I am currently working with two tables.

status:

id INT(4) AUTO_INCREMENT
username VARCHAR(20)
text LONGTEXT
datetime VARCHAR(25)
attachment VARCHAR(11)
timestamp VARCHAR(50)

friends:

id INT(2) AUTO_INCREMENT
added INT(1)
userto VARCHAR(32)
userfrom VARCHAR(32)

I would like to add the option for a user to filter statuses for only their friend's statuses, and display them with the newest one first. By this I mean most recent status, not newest per friend, which I suspect can be done with:

ORDER BY status.id DESC

How would I order the statuses based on the statuses of the users on the person's friends list?

Try this

SELECT      status.*
FROM        status
JOIN        friends
ON          status.username = friends.userto
WHERE       friends.userfrom = '$username'
UNION
SELECT      status.*
FROM        status
JOIN        friends
ON          status.username = friends.userfrom
WHERE       friends.userto = '$username'
ORDER BY    status.id DESC;

this query loads statuses from usernames on either end of the friendship relationship that includes $username. Union is used to glue two lists top to bottom. Join is used to glue two lists side by side and align them on the author's username.

Well, without any sample data it would be hard to do this for sure, but I would walk through it this way.

The statuses we want to show (regardless of order) are those the user is friends with. So, let's get the friends of Adam for example:

SELECT DISTINCT userto
FROM friends
WHERE userfrom = 'Adam'
UNION
SELECT DISTINCT userfrom
FROM friends
WHERE userto = 'Adam';

At this moment, I should point out that in your friends table the usernames are VARCHAR(32) and in the status table they are VARCHAR(20), I would assume they should be the same.

So, now you can filter the status based on whether or not the username is in the above subquery, and you could order by id descending, assuming you add them in order, but the best way would be to order by the timestamp on the status:

SELECT *
FROM status
WHERE username IN 
   (SELECT DISTINCT userto
   FROM friends
   WHERE userfrom = 'Adam'
   UNION
   SELECT DISTINCT userfrom
   FROM friends
   WHERE userto = 'Adam')
ORDER BY datetime DESC;

EDIT

I would also rethink your variables for datetime and timestamp, as well as rethink the name. While these are valid, they are also reserved words (DATETIME and TIMESTAMP are data types in MySQL). A possible reconstruction of your status table could be:

id INT(4) AUTO_INCREMENT
username VARCHAR(32)
statusText LONGTEXT
statusPostDate DATETIME
attachment VARCHAR(11)

The DATETIME variable will hold both the date and time portions for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM