Ordering a mysql query? - php

I have 2 tables, Pages and LinkPages.
Within Pages i have the fields:
pageID (the identifier of the page),
startmemberID (the id of the member that created the page),
startDate (date the page was created).
In LinkPages I have:
pageID (to link with the page),
linkmemberID (member linking with the page),
joinDate (date member linked with the page).
What sql query would i use to get all information on the pages with a particular id and then order it by the date the page was started.
I got this far:
SELECT * FROM LinkPages WHERE linkmemberID='MEMBERID' LIMIT 5
but obviously i haven't ordered them here, would i need to use a join?
Many Thanks,
Jai

Try this:
SELECT * FROM LinkPages
INNER JOIN Pages ON Pages.pageID = LinkPages.pageID
WHERE linkmemberID='MEMBERID'
ORDER BY startDate DESC
LIMIT 5

SELECT lp.pageID, lp.linkmemberID, lp.joinDate
FROM LinkPages lp, Pages p
WHERE lp.linkmemberID='MEMBERID' AND lp.pageID = p.pageID
ORDER BY p.startDate DESC
LIMIT 5

You have two options, either you can JOIN or you can use a subquery:
SELECT * FROM LinkPages WHERE linkmemberID='MEMBERID'
ORDER BY
(SELECT startDate FROM Pages WHERE Pages.pageID = LinkPages.PageID) DESC
LIMIT 5
For good measure, here's the join:
-- be sure to use L.* here, otherwise you get all of the columns from
-- pages as well
SELECT L.* FROM LinkPages L
INNER JOIN Pages P ON P.pageID = L.pageID
WHERE linkmemberID='MEMBERID'
ORDER BY P.startDate DESC LIMIT 5

SELECT lp.*
FROM LinkPages lp, Pages p
WHERE lp.pageId = p.pageId
AND lp.linkmemberID='MEMBERID'
ORDER BY p.startDate
LIMIT 5
sorry - forgot the ORDER BY ...

Related

Getting two different results by one SQL query

First I am new to SQL and PHP.
I have created a simple social networking web app so users can post and follow others to see new posts from them.
At home page a user can first see posts from all users he is followong.
but what i want is to make the user see some other random popular posts that will be ordered by Likes.
here what i have done to get posts from users i follow:
SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC LIMIT 10
Now let's say you are following only 1 person. and that person has only one post. here you will see no more than a post!
That's why i want to show more posts when a user has already seen all posts.
i want some easy way to get other posts when the above query has done getting some specific posts.
This is the next query i'd like to execute.
SELECT * FROM posts ORDER BY post_likes DESC LIMIT 10
I wouldn't recommend union, because it incurs overhead for removing duplicates.
Instead, you can use a LEFT JOIN:
SELECT p.*
FROM posts p LEFT JOIN
follows f
ON p.author_id = f.follows_id AND
f.followerID = :myID
ORDER BY (f.follows_id IS NOT NULL) DESC,
(CASE WHEN f.follows_id IS NOT NULL THEN p.id END),
p.post_likes DESC
LIMIT 10;
The ORDER BY puts the followed posts first. The other two clauses order each of the groups by the criteria you want.
You may use UNION to do what you want
(SELECT * FROM posts WHERE author_id in
(SELECT followedID FROM follows WHERE
followerID=:myID)
ORDER BY id DESC limit 0,10)
union
(SELECT * FROM posts ORDER BY post_likes DESC limit 0,10)
LIMIT 0, 10
UNION will automatically append the 2nd query result to the 1st query result, and then show only the number of records specified by the LIMIT clause
Please note that union works only if the queries are of the same structure (which in this case is positive)
Please note that the use of parenthesis is mandatory if you use order by or limit or both
I have used 3 limit clauses (one for each query , and one for the final result of union) AND Both queries have ORDER BY clause. This is to make sure that the records extracted are what you want. (to show the followed posts first, and both are ordered properly)

Using order by DESC or ASC in mysql queries with UNION keyword

In my page I used the following query for displaying choices starts from current time to old time of choices. But it selects the row starts from old time choices to current time choices.
I want to display the choices starts from current time to old one
$result=mysql_query("(SELECT choice_id,poll_id,choicecreationtime from je_addchoice ORDER BY choicecreationtime DESC)
UNION
(SELECT choice_id,poll_id,datetime_voted from je_user_vote ORDER BY datetime_voted DESC)");
I dont know why this problem occurs. If I don't use the UNION means it works fine. For example. The below query shows the order of current time to old
$result = mysql_query("SELECT * FROM je_addchoice, je_addpoll where je_addpoll.privacy='0' AND je_addpoll.start_date <= '$check_date' AND je_addpoll.end_date >='$check_date' AND je_addpoll.poll_id=je_addchoice.poll_id order by je_addchoice.choicecreationtime desc");
Anybody can help me to solve this problem
wrap the unioned queries by subquery and order them on the outer query
SELECT *
FROM
(
SELECT choice_id, poll_id, choicecreationtime AS TIME
FROM je_addchoice
UNION
SELECT choice_id, poll_id, datetime_voted AS TIME
FROM je_user_vote
) s
ORDER BY TIME DESC
UPDATE 1
SELECT choice_id, poll_id, choicecreationtime AS TIME
FROM je_addchoice
UNION
SELECT choice_id, poll_id, datetime_voted AS TIME
FROM je_user_vote
ORDER BY Time DESC
As documented under UNION Syntax:
To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
However, use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. Therefore, the use of ORDER BY in this context is typically in conjunction with LIMIT, so that it is used to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.
To use an ORDER BY or LIMIT clause to sort or limit the entire UNION result, parenthesize the individual SELECT statements and place the ORDER BY or LIMIT after the last one. The following example uses both clauses:
(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;
A statement without parentheses is equivalent to one parenthesized as just shown.
Try this:
SELECT choice_id, poll_id, dt
FROM (SELECT choice_id, poll_id, choicecreationtime dt FROM je_addchoice
UNION
SELECT choice_id, poll_id, datetime_voted dt FROM je_user_vote ) AS A
ORDER BY dt DESC

PHP MySQL Top 5 Referers Function

I have a table called users which looks like:
-id
-email
-login
-admin
-coins
-cash
-premium
-IP
-pass
-ref
-signup
-online
-promote
-activate
-banned
-rec_hash
-country
-c_changes
-sex
-daily_bonus
If say user with id 81 referred 10 people then those 10 people would have "81" in their ref column.
I would like to create a top 5 referral table but I'm having trouble with the query and displaying that in PHP, would anybody be able to help?
I FORGOT TO MENTION IF THEY HAVE NO REFERRAL IT SHOWS AS 0 HOW WOULD I EXCLUDE 0 FROM BEING SHOWN AS A REFERRAL?
You can do it in a single SQL statement like this:
SELECT ref, COUNT(*) AS num FROM users
GROUP BY ref ORDER BY num DESC LIMIT 5
But that will just get you the 5 IDs, rather than their user rows. You can then perform a further query to get the actual rows. Alternatively, use the above query with a join to do it all in one.
IF THEY HAVE NO REFERRAL IT SHOWS AS 0
messy design - this should be null. Regardless...
SELECT u.login, ilv.referred
FROM
(SELECT ref, COUNT(*) AS referred
FROM users
WHERE ref IS NOT NULL
AND ref>0
GROUP BY ref
ORDER BY COUNT(*) DESC
LIMIT 0,5) ilv
INNER JOIN users u
ON ilv.ref=users.id
ORDER BY ilv.referred DESC;
Or and SQL like this:
SELECT u.*, COUNT(*) as referrers FROM users r JOIN users u ON r.ref = u.id
GROUP BY u.id ORDER BY referrers DESC LIMIT 5
It is faster to use just one statement even with a join on the same table.

How to structure this SQL query?

So basically I'm getting notifications of new content on my website. I have 4 tables -
articles
media
updates
comments
Each table has a set of its own columns (I can include these if anyone wants). There is one distinct column every table has, this is the timestamp column (a big int formatted column with data from the PHP time() function). My solution to getting the last 30 modifications is to select the first 30 rows from these 4 tables ordered by timestamp descending.
Here is the query I have so far, it doesn't work and I'm wondering if someone could help me. -
SELECT * FROM `articles`
UNION SELECT * FROM `media`
UNION SELECT * FROM `updates`
UNION SELECT * FROM `comments`
ORDER BY `timestamp` DESC
LIMIT 30
EDIT:
I was also using another query before -
SELECT * FROM `articles` ,`media` ,`updates` ,`comments`
ORDER BY `timestamp` DESC
LIMIT 30
and kept getting this error -
Column 'timestamp' in order clause is ambiguous
EDIT 2
I realise now I have to use the AS clause in my statement to combine these results into one table.
SELECT a.*,m.*,u.*,c.* from articles AS a
LEFT JOIN media AS m ON (m.timestamp = a.timestamp)
LEFT JOIN updates AS u ON (u.timestamp = a.timestamp)
LEFT JOIN comments AS c ON (c.timestamp = a.timestamp)
ORDER BY timestamp desc LIMIT 30
Your union can work, but only if you can create some sort of common field list. For example, lets say you have a description field in each table, with different names. Something like this will work...
SELECT TimeStamp,'Articles',Art_desc AS Description FROM articles
UNION ALL
SELECT TimeStamp,'Media',Media_Desc FROM Media
UNION ALL
SELECT TimeStamp,'Updates',Update_Desc FROM Updates
UNION ALL
SELECT TimeStamp,'Comments',Comment FROM Comments
ORDER BY timeStamp DESC LIMIT 30
In essence, you are creating result sets of 3 consistent columns, so UNION will work in this case.

Most Popular Mysql Row over last 7 days

In one table I have
ID, PAGE_ID, DATE
Each time a page is loaded, the DATE, PAGE_ID [from the page table below] are loaded into the table above.
I am trying to calculate and sort pages by popularity. The page table contains:
ID [PAGE_ID], DESCRIPTION, DATE
I have no idea where to start.
select L.PAGE_ID, P.DESCRIPTION, count(L.ID) from LOADED_PAGE L
inner join PAGE P on P.ID = L.PAGE_ID
where L.DATE > :sevenDaysAgo
group by L.PAGE_ID, P.DESCRIPTION
order by count(L.ID) desc
will give you the list of loaded pages, from the most popular to the least one.
select
id_page,
count(*) as popularity
from table
where date >= curdate() - interval 7 day
group by id_page
order by popularity desc

Categories