3

My database table is (it has millions of records)

    sitename        rank     date
    facebook.com    1       2016-2-13
    gmail.com       2       2016-2-13
    yahoo.com       3       2016-2-13
    aol.com         4       2016-2-13
    facebook.com    1       2016-2-14
    gmail.com       2       2016-2-14
    yahoo.com       4       2016-2-14
    aol.com         3       2016-2-14

I want to find sites whose ranking has changed. in the above illustration yahoo and aol has changed. I tried several queries but cant get it to work.

11
  • something like this bit.ly/1SpK6Mj Commented Feb 14, 2016 at 12:31
  • please specify your question: changed since some date or ever Commented Feb 14, 2016 at 12:39
  • lets say changed over 1 month. Commented Feb 14, 2016 at 12:40
  • SQL SERVER or MYSQL? and look at my answer , should do the trick Commented Feb 14, 2016 at 12:44
  • even top 1 with ties with filter by date might satisfy your needs Commented Feb 14, 2016 at 12:47

5 Answers 5

2

Its a simple select, group by and having query like this:

SELECT sitename,MAX(rank) - MIN(rank) as changed
FROM YourTable
GROUP BY sitename
HAVING COUNT(DISTINCT rank) > 1
Sign up to request clarification or add additional context in comments.

3 Comments

yeah, but if you run select *, the date will still be 2016-02-13
i also want the change / difference. Look at the bit.ly link above. Any idea ?
I need to show date-wise change. By using Max() and Min() you arent taking account of date. There's no way to tell if change is negative or positive.
1

Based on the ideas given, here's what I've got:

SELECT sitename, rank, rank - (SELECT rank from sites WHERE sitename = main.sitename ORDER BY date LIMIT 1,2) as rankChange
FROM sites as main
WHERE date <= NOW()
GROUP BY sitename
HAVING COUNT(DISTINCT rank) > 1

This will return

sitename    rank    rankChange
aol.com        4             1
yahoo.com      3            -1

If you remove HAVING COUNT(DISTINCT rank) > 1 from the query, you will see the set with the unchanged webs:

sitename    rank    rankChange
aol.com        4             1
facebook.com   1             0
gmail.com      2             0
yahoo.com      3            -1

5 Comments

@johnyyy there's a whole chapter on that in mysql documentation: dev.mysql.com/doc/refman/5.5/en/select-optimization.html Sorry, but I can't generate millions of rows of mock data just to optimize this query for you.
is there any other way using max(date) and min(date) ?
@johnyyy I think this is an answer. How to optimize that is another question
@Ivan The query keeps loading, havent seen the result of this query
@johnny Have you made restrictions in where clause by date? I suppose you have a start and end date for which you want a change. In example there is no restriction in fact
0

you can do by like this:

select * from your_table t_outer
group by sitename, date
having rank <> (select rank from your_table t_internal 
where t_outer.date > t_internal.date and t_outer.sitename = t_internal.sitename
order by t_internal.date limit 1)

and it is output:

enter image description here

1 Comment

@johnyyy it gives me the output in the picture I upload
0

Something like following. And you need a record for every site every day

SELECT sitename, MAX(rank) - MIN(rank) as ChangeRank
FROM ChangeHistoryTable
WHERE date between dateFromWhichYouNeedChanges and dateToWhichYouNeedChanges
GROUP BY sitename
HAVING COUNT(DISTINCT rank) > 1

2 Comments

the result is both yahoo and aol show -1 (if I use now())
@Nordenheim Yes, I missundertstood the task. Then your answer is right
0

Try this:

Select sitename from table group by sitename having count(*) > 1 order by sitename, rank DESC

1 Comment

Now thats almost a copy of my answer, and still won't work since you are missing the distinct in the count which will results in returning every one that appeared twice or more on the table no matter if the rank changed. Also, order by in unnecessary .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.