Order by rand() with same id - mysql

Hi everyone i'm looking for a little help with a query.
I have 2 tables
I need to get all answers from a questions randomly.With the query
Select * From questions,answers WHERE questions.id = answers.iddomanda
the result is perfect but if i use the order by rand this is the outcome.
there's a way to get, randomly, the questions end, randomly, the answers?
Something like
id iddomanda question answer
4 4 Come va ? bene
4 4 Come va ? male
1 1 Come ti chiami ? Michele
1 1 Come ti chiami ? Carlo
2 2 Di dove sei? San Salvo
2 2 Di dove sei ? Vasto
3 3 Dove vai ? Lontano
3 3 Dove vai ? Lontanissimo
3 3 Dove vai ? In giro
3 3 Dove vai ? Di la
thx for help

all you need to do is randomize the question id and then join your answers to it like so.
SELECT t.id, t1.iddomanda, t.question, t1.answer
FROM
( SELECT id, domanda as question
FROM questions
ORDER BY RAND()
) t
LEFT JOIN
( SELECT iddomanda, risposta as answer
FROM answers
) t1 on t1.iddomanda = t.id;
the nice thing about this query is you are being very minimalistic.. the questions table is going to be much smaller than the answers table so you just need to randomize ONE table and the smaller one at that... and then when you join it will join them to the already randomized table!
DEMO

Use a subquery to select the questions and answers in random order:
SELECT *
FROM (SELECT *
FROM questions
ORDER BY RAND()
LIMIT 10) AS q
JOIN (SELECT *
FROM answers
ORDER BY RAND()
LIMIT 100) AS a
ON q.id = a.iddomanda
LIMIT 10

Ordering by rand() will give a random order.
What you want is an order by first Question id and second in equal question ids randomly:
... order by id, RAND() ...

Related

sql select with count condition

I have 2 tables in my DB, first table called "questions" and hold questions with id, second table called "answers" and hold answers for the questions (as multiple choices).
how to select questions that have less than 4 answers?
questions table:
id question
1 what is ...?
2 how many ...?
3 Is ....?
answers table
id question_id answer
1 1 54
2 1 11
3 1 22
4 2 England
5 1 5
6 2 Turkey
how to select questions that have answers less than 4?
thanks,
select questions.id, questions.question from questions
inner join answers on questions.id = answers.question_id
group by questions.id, questions.question having count(questions.id) <4
here you go.
use this :
SELECT *
FROM questions
WHERE id in
(
SELECT question_id
from answers
group by question_id
having count(question_id) <4
)

Selecting id and value where max occurs

I've solved one issue and ran into another. Basicaly i want to select question_id, answer and maximum number of occurences. I run my query from basic table that gathers questions and answers to them (question id represents question and answer represents answer from 0 to 5 that corresponds to other table but that doesn't matter).
**survey_result**
question_id
answer (int from 0 to 5)
Sample survey_result:
question_id answer
1 3
1 5
1 2
2 2
2 0
2 4
Here's the query, it's purpose is to check for every single question, which answer (from 0 to 5) occured the most.
select question_id, answer, max(occurence_number) FROM
(select question_id, answer, count(*) as occurence_number
from survey_result
group by question_id, answer
order by question_id asc, occurence_number desc) as results
GROUP BY question_id
So a sub query results in something like this:
question_id answer occurence_number
1 0 12
1 1 20
1 2 34
1 3 5
1 4 9
1 5 15
But main query results something like this:
question_id answer occurence_number
1 0 12
2 0 20
3 0 34
4 0 5
So the problem is that it always shows answer 0, and i want to get correct answer number.
Sadly a bit redundant due to MySQL's lack of a WITH statement, but this should do what you want. In case of a tie, it will return the higher answer.
SELECT s1.question_id, MAX(s1.answer) answer, MAX(s1.c) occurrences
FROM
(SELECT question_id, answer, COUNT(*) c
FROM survey_result GROUP BY question_id,answer) s1
LEFT JOIN
(SELECT question_id, answer, COUNT(*) c
FROM survey_result GROUP BY question_id,answer) s2
ON s1.question_id=s2.question_id
AND s1.c < s2.c
WHERE s2.c IS NULL
GROUP BY question_id
An SQLfiddle to play with.
I think you are overcomplicating it, try this:
select question_id, answer, count(*) as occurence_number
from survey_result
group by question_id, answer

MySQL Query limit 3 or more if last 3 are equal?

I need to limit my result to 3 row (an example), but if 3rd result is equal to 4th, print also 4th, and so on.
To explain: from this table
id punteggio
1 100
2 200
3 70
4 100
5 54
6 201
7 200
if I do
SELECT * FROM table ORDER BY punteggio DESC LIMIT 3
i need in every case to print following situation:
id punteggio
6 201
2 200
7 200
1 100
4 100
Because my "three" best points are in reality 5 of 7, cause 2 and 7 have same points, like 1 and 4...
I dont'know in advance min and max points, otherwise i would do
"WHERE punteggio >= 100"
Thank you very much!
UPDATE
Unfortunately my scenario changed:
punteggio born from SUM from another table:
id idPersona punteggio
1 1 30
2 1 -10
3 2 50
4 3 60
5 2 -10
6 3 150
7 1 190
and so on...
i've tried do:
SELECT persone.nome,
SUM(transazioni.importoFinale) AS punti
FROM transazioni
INNER JOIN persone ON persone.idPersona = transazioni.idPersona
INNER JOIN
(SELECT DISTINCT(SUM(transazioni.importoFinale)) AS punti,
persone.nome
FROM transazioni
INNER JOIN persone on persone.idPersona = transazioni.idPersona
GROUP BY persone.idPersona
ORDER BY punti DESC
LIMIT 3) subq ON transazioni.punti = subq.punti
ORDER BY punti DESC
but it doens't function...
Thank you to all!
Use a subquery join to get the DISTINCT set of 3 greatest values for punteggio and join it against the main table to retrieve all rows that have those values.
SELECT
id,
punteggio
FROM
yourtable
/* subquery gets the top 3 values only */
/* and the INNER JOIN matches it to all rows in the main table having those values */
INNER JOIN (
SELECT DISTINCT punteggio as p
FROM yourtable
ORDER BY punteggio DESC
LIMIT 3
) subq ON yourtable.punteggio = subq.p
ORDER BY punteggio DESC
Here's a demo on SQLFiddle.com
SELECT id, punteggio
FROM yourtable
WHERE punteggio IN (
SELECT * FROM (
SELECT DISTINCT punteggio
FROM yourtable
ORDER BY punteggio DESC
LIMIT 3
) AS temp
);
Note that the select * is present to work around mysql not supporting limits in subqueries in an IN() clause.

SELECT in mysql [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
selecting items that come after a specific value
i asked this allready bu explained it very bad so i'm gonna do it right this time.
I have a mysql table like this:
ISBN title author price amount
978-0060850524 A Brave New World Aldous Huxley 6.49 7
978-0061743528 To Kill a Mockingbird Harper Lee 12.89 0
978-0142000670 Of Mice and Men John Steinbeck 5.99 89
978-0452284234 Nineteen Eighty-Four George Orwell 10.85 90
978-0452284241 Animal Farm George Orwell 9.80 24
978-0553574166 The Hutt Gambit A.C. Crispin 7.99 2
978-0553578850 The Mandalorian Armor. K.W. Jeter 7.99 20
978-0571056866 Lord of the Flies William 7.70 45
978-0765340788 The Machine Crusade Brian Herbert 7.99 14
978-0861404216 The Colour of Magic Terry 29.16 3
I want to create a query wich does the following.
I have a variable wich contains the ISBN of 1 of the products.
the query should select all the products ordered by the ISBN bust starting with the ISBN that was given in the variable. so if the ISBN is from item 4 the result should show all 10 books starting with item 5(yes it should start from 1 item after the item in the variable then 6,7,8,9,10,1,2,3,4 ,5
You can do this in a single query in MySql, like so:
SELECT * FROM `yourtable`
order by ISBN>'Your ISBN' desc, ISBN asc
Note: using ISBN>'Your ISBN' desc in the order by will ensure that
the higher ISBNs appear first, followed by the lower ones. Thereafter each group
is ordered by ISBN.
Only solution I see would be two queries with UNION :
SELECT *
FROM yourtable
WHERE ISBN = 'Your ISBN'
UNION
SELECT *
FROM (
SELECT *
FROM yourtable
WHERE ISBN <> 'Your ISBN'
ORDER BY ISBN
LIMIT 9
);
I'm not a huge fan of ORDER BY and LIMIT in subqueries, though...
Something like this should perform well:
(SELECT * FROM t1 WHERE ISBN > '978-0452284234' ORDER BY ISBN)
UNION ALL
(SELECT * FROM t1 WHERE ISBN <= '978-0452284234' ORDER BY ISBN)
SELECT *
FROM (
SELECT *
FROM books bo
WHERE isbn >
(
SELECT isbn
FROM books bi
WHERE id = 4
)
ORDER BY
isbn
LIMIT 10
) q
UNION ALL
SELECT *
FROM (
SELECT *
FROM books bo
ORDER BY
isbn
LIMIT 10
) q
LIMIT 10

MySQL query: select how many times was every option selected

I have 2 mysql tables
1. questions: with the following columns: id, title, answer1, answer2, answer3, answer4, answer5, nranswers.
and
2. answers with the following columns: id, questionid, userid, answer
Every question has maximum 5 answers( it can have between 2 and 5 answers). My problem is that I want to select from my database, for a given question, how many times was every option selected.
For example, let's suppose I have the question with the id 46, with 4 answers, and 48 users voted for the option #2, 37 users for the option #1 and 39 for the option #4.
I want a query that selects that and write these things:
1 37
2 48
3 0
4 39
P.S. VERY IMPORTANT! IT MUST COUNT ONLY NRANSWERS ANSWERS, AND IT MUST ECHO THE ONES THAT WEREN'T VOTED BEFORE.
Best way to do this: change table defs:
Questions (Question_ID, title)
Answers (Answer_ID, Question_ID, answer_text)
Votes (User_ID, Answer_ID)
Which contains the same data as your def, but is in first normal form. Selecting the counts is now really easy
SELECT
a.Answer_ID,
COUNT(v.User_ID)
FROM
Questions q
LEFT JOIN Answers a ON q.Question_ID = a.Question_ID
LEFT JOIN Votes v ON a.Answer_ID = v.Answer_ID
WHERE q.Question_ID = 46 -- or any other question ID
GROUP BY a.Answer_ID
ORDER BY a.Answer_ID;
SELECT q.id as question, a.answer as answer, count(a.answer) as count FROM questions q, answers a Group by q.id,a.answer
Problem with above that it will return as follows
question answer Count
1 1 37
1 2 48
1 4 39
1 3 0 this is missing
OR
SELECT a.question_id, a.answer, count(a.answer) FROM test.answers a Group by a.question_id, a.answer