-2
(SELECT schemename, message FROM RandomMessagesSet where type = 'ES' ORDER BY RAND()) 
 UNION ALL (SELECT schemename, message FROM RandomMessagesSet where type = 'HE' ORDER BY RAND()) ORDER BY schemename; 

This gives the list of all the messages with their scheme names. Is there a way to get 3 each of type "ES" and 2 each of type "HE" for each of schemename?

This is not a homework but part of a research problem that would feed into designing a user study. I tried using LIMIT and JOIN by looking at most of the posts here but still stuck.

Please help me. Your help would assist me to design my second last experiment for my PhD.

EDIT: Thanks to the most empathetic person who downvoted this. You should try doing a PhD yourself to get the feel of it.

I'm afraid I cannot provide sample data due to nature of research work.

Desired output:

Desired output

Rosemary
  • 71
  • 10
  • Could you please provide sample input and output table(s). – Nae Oct 10 '18 at 15:38
  • How exactly have you tried `LIMIT` and `JOIN`? – Nae Oct 10 '18 at 15:43
  • @Nae As I mentioned it's a part of my PhD, it's difficult to make new sample data. Doing a PhD is immense pressure and hard work. I posted this here to get most possible help, but with research, the people in this community is quite biased and critical apart from a few exceptions. I'm running short of time as well and not really in a mindset to explain to all what I did which didn't give the desired output. – Rosemary Oct 10 '18 at 16:03
  • 1
    This is not working ? (SELECT schemename, message FROM RandomMessagesSet where type = 'ES' ORDER BY RAND() limit 3) UNION ALL (SELECT schemename, message FROM RandomMessagesSet where type = 'HE' ORDER BY RAND() limit 2) ORDER BY schemename; – DanB Oct 10 '18 at 16:06
  • 1
    @DanielBlais That produces only 5 messages but I need 5 * each of the scheme names. So if I have 6 scheme names, there has to (3+2)*6 messages in total. Do you have any ideas? – Rosemary Oct 10 '18 at 16:11
  • 1
    Sorry, I misread your question. Yes you can. Which version of mysql do you use? For Mysql 8, you can use ranking function http://www.mysqltutorial.org/mysql-window-functions/mysql-rank-function/ For older version, see this post : https://stackoverflow.com/questions/3333665/rank-function-in-mysql – DanB Oct 10 '18 at 16:15
  • 1
    If you cannot share the data, atleast giving out minimal and relevant table structure would work. Not to be rude, but all of us are trying to voluntarily help each other. And quite a bit of us are well qualified. Don't antagonize SO community by using sarcastic words like "You should try doing a PhD yourself to get the feel of it." – Madhur Bhaiya Oct 10 '18 at 16:30
  • @MadhurBhaiya I know there are few who try to really help. I got that in the past along with many bashing me. I've been downvoted to the nature of my questions. My question is a logical question, the data doesn't matter here. It is so difficult to explain a research problem here. – Rosemary Oct 10 '18 at 16:33
  • 1
    @Rosemary no one wants your real data. Please read: [Why should I provide an MCVE for what seems to me to be a very simple SQL query?](https://meta.stackoverflow.com/q/333952/2469308) I know doing research can be exhausting at times (been there); just try to frame your problem with minimal unreal data, but reflecting the "nature" of your problem. Otherwise there will be just wild guesses, and it will get more frustrating for you. – Madhur Bhaiya Oct 10 '18 at 16:44
  • What is your MySQL **server** version ? If it is **8.0** or above, there is a straightforward solution available. let me know the version, I will give a try! – Madhur Bhaiya Oct 10 '18 at 16:51
  • @MadhurBhaiya Thank you. I can upgrade which isn't a problem. I've added the desired output outline. – Rosemary Oct 10 '18 at 16:58

1 Answers1

0

In MySQL 8.0 and above, we can use Window Functions. We use a Partition over an expression of concatenated string of schemename and type.

Try (DB Fiddle):

SELECT dt.schemename, 
       dt.type, 
       dt.message
FROM 
(
 SELECT 
   schemename, 
   type, 
   message, 
   ROW_NUMBER() OVER (PARTITION BY CONCAT(schemename, '-', type) 
                      ORDER BY RAND()) AS row_num 
 FROM RandomMessagesSet
) AS dt 
WHERE (dt.type = 'ES' AND dt.row_num <= 3) OR 
      (dt.type = 'HE' AND dt.row_num <= 2) 
ORDER BY dt.schemename 
Madhur Bhaiya
  • 28,155
  • 10
  • 49
  • 57
  • Somehow the query looks fine but when I run it, I get only 3 messages :( – Rosemary Oct 10 '18 at 18:44
  • @Rosemary let me check it again. Query I have double checked though. Are you sure that you have enough data ? – Madhur Bhaiya Oct 10 '18 at 18:47
  • @Rosemary please check this DB Fiddle Link - https://www.db-fiddle.com/f/7kfztHdvGZ2mpM62cRryU5/0 The query is working perfectly fine for me. – Madhur Bhaiya Oct 10 '18 at 19:07
  • I think it's the issue with the data I have as I could only give you a rough representation of the data. Thank you for your help :) – Rosemary Oct 10 '18 at 19:38