Generate a query that show the times that questions get wrong - mysql

I have a table named countwronganswer with columns cwa_id, question_num. How can I generate a table with query that shows two columns, one column lists all the question_num and second column lists the number of times that cwa_id that related to the question_num.
Question Number |Total # of Mistake |
1 12
2 22
..etc
ATTENTION: This question was asked without the awareness of the existence of count or Groupby method because of the knowledge level at that state. Count() or Groupby() were the key to generate the 2nd column of total # values which I did not aware of completely, therefore, any attempt, at that point of time, to write the code for the data will be close to meaningless. Vote up if possible if you think its useful or resolved your issue.

Probably something like this
SELECT question_num, COUNT(cwa_id) total_mistakes
FROM countwronganswer
GROUP BY question_num

select question_num , count(cwa_id)
from tableName group by question_num

Related

MySQL Same Table Join Issue

In short, all data is sorted into rows per value.
I have 4 columns I need to work with, ENTRY_ID, FIELD_ID, VALUE, and FORM_ID which is what I want to use to sort entries per form.
This is driving me nuts because I know it should be simple.
I have 2 examples I need to get out, one being COLUMNS based on all FIELD_IDs and VALUES per ENTRY_ID in a row, another that use UNIQUE VERSIONS OF THE VALUES AS columns (e.g. think days of the week).
If anyone can help it would be amazing.
If I understand your question, you want to perform some pivoting of your table.
Take a look at this answer:
MySQL pivot table

mysql group_concat alternative or multiple rows as columns

Before i start my question i cover briefly what the problem is:
I have a table that stores around 4 million 'parameter' values. These values have an id, simulation id and parameter id.
The parameter id maps to a parameter table that basically just maps the id to a text like representation of the parameter x,y, etc etc
The simulation table has around 170k entries that map parameter values to a job.
There is also a score table which stores the score of each simulation , simulations have varying scores for example one might have one score another might have three. The scores tables has a simulation_id column for selecting this.
Each job has an id and an objective.
Currently im trying to select all the parameter_values who's parameter is 'x' and where the job id is 17 and fetch the score of it. The variables of the select will change but in princible its only really these things im interested in.
Currently im using this statement:
SELECT simulation.id , value , name , ( SELECT GROUP_CONCAT(score) FROM score WHERE score.simulation_id = simulation.id ) AS score FROM simulation,parameter_value,parameter WHERE simulation.id=parameter_value.simulation_id AND simulation.job_id = 17 AND parameter_value.parameter_id=parameter.id AND parameter.name = "$x1"
This works nicley except its taking around 3 seconds to execute. Can this be done any faster?
I don't know if it would be faster doing a query before this a pre-calculating the parameter_ids im searching for and doing an WHERE parameter_id IN (1,2,3,4) etc.
But i was under the impression SQL would optimize this anyway?
I have created index's where ever possible but cant get faster than the 2.7 seconds mark.
So my question would be:
Should i pre-calculate some values and avoid the joins,
Is there another other than group_concat to get the scores
and is there any other optimizations i could make to this?
I should also add that the scores must be in the same row or at least return sorted so i can easily read them from the result set.
Thanks,
Lewis

it is possible to "group by" without losing the original rows?

i have a query like this:
ID | name | commentsCount
1 | mysql for dummies | 33
2 | mysql beginners guide | 22
SELECT
...,
commentsCount // will return 33 for first row, 22 for second one
FROM
mycontents
WHERE
name LIKE "%mysql%"
also i want to know the total of comments, of all rows:
SELECT
...,
SUM(commentsCount) AS commentsCountAggregate // should return 55
FROM
mycontents
WHERE
name LIKE "%mysql%"
but this one obviously returns a single row with the total.
now i want to merge these two queries in one single only,
because my actual query is very heavy to execute (it uses boolean full text search, substring offset search, and sadly lot more), then i don't want to execute it twice
is there a way to get the total of comments without making the SELECT twice?
!! custom functions are welcome !!
also variable usage is welcome, i never used them...
You can cache the intermediate result to a temporary table, and then do the sum over this table
One obvious solution is storing intermediate results withing another 'temporary' table, and than perform aggregation in the second step.
Another solution is preparing a lookup table containing sums you need (but there obviously needs to be some grouping ID, I call it MASTER_ID), like that:
CREATE TABLE comm_lkp AS
SELECT MASTER_ID, SUM(commentsCount) as cnt
FROM mycontents
GROUP BY MASTER_ID
Also create an index on that table on column MASTER_ID. Later, you can modify your query like that:
SELECT
...,
commentsCount,
cnt as commentsSum
FROM
mycontents as a
JOIN comm_lkp as b ON (a.MASTER_ID=b.MASTER_ID)
WHERE
name LIKE "%mysql%"
It also shouldn't touch your performance as long as lookup table will be relatively small.
A GROUP BY on one of the ID fields might do the trick. This will then give you the SUM(commentsCount) for each ID.
The query in your question is not detailed enough to know which of your fields/tables the ID field should come form.

MYSQL - create single record out of similar rows, chose values of greatest length for most columns

Here is my case, I have a database table with below fields:
name
place_code
email
phone
address
details
estd
others
and example data
If you look at the above example table, first three records are talking about xyz and place code 1020.
I want to create a single record for these three records based on
substring(name,1,4)
place_code
(I am lucky here for all the similar records satisfies this condition and unique in the table.)
For the other columns which record column length has max. For example again for the above 3 records email should be test#te.com, phone should be 657890 and details should be "testdetails".
This should be done for all the table. (Some has single records and some has max 10 records.)
Any help on query that helps me to get the desired result?
Answer
Some one posted the below answer and deleted it . But that looks a good solution
SELECT max(name),
place_code,
max(email),
max(phone),
max(address),
max(details),
max(estd),
max(others)
FROM table_x
GROUP BY substring(name,1,4),place_code
Please let me know if you guys see any issues in it ?
Thank You all
Kiran
You need the awesome GROUP_CONCAT aggregate function.
SELECT place_code,
substring(name,1,4) name,
GROUP_CONCAT(email),
GROUP_CONCAT(Phone),
GROUP_CONCAT(details)
FROM table
GROUP BY place_code, substring(name,1,4)
It has options allowing you to control things like the order of items in the string and the separators. See http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
SELECT max(name),
place_code,
max(email),
max(phone),
max(address),
max(details),
max(estd),
max(others)
FROM table_x
GROUP BY substring(name,1,4),place_code

randomizing large dataset

I am trying to find a way to get a random selection from a large dataset.
We expect the set to grow to ~500K records, so it is important to find a way that keeps performing well while the set grows.
I tried a technique from: http://forums.mysql.com/read.php?24,163940,262235#msg-262235 But it's not exactly random and it doesn't play well with a LIMIT clause, you don't always get the number of records that you want.
So I thought, since the PK is auto_increment, I just generate a list of random id's and use an IN clause to select the rows I want. The problem with that approach is that sometimes I need a random set of data with records having a spefic status, a status that is found in at most 5% of the total set. To make that work I would first need to find out what ID's I can use that have that specific status, so that's not going to work either.
I am using mysql 5.1.46, MyISAM storage engine.
It might be important to know that the query to select the random rows is going to be run very often and the table it is selecting from is appended to frequently.
Any help would be greatly appreciated!
You could solve this with some denormalization:
Build a secondary table that contains the same pkeys and statuses as your data table
Add and populate a status group column which will be a kind of sub-pkey that you auto number yourself (1-based autoincrement relative to a single status)
Pkey Status StatusPkey
1 A 1
2 A 2
3 B 1
4 B 2
5 C 1
... C ...
n C m (where m = # of C statuses)
When you don't need to filter you can generate rand #s on the pkey as you mentioned above. When you do need to filter then generate rands against the StatusPkeys of the particular status you're interested in.
There are several ways to build this table. You could have a procedure that you run on an interval or you could do it live. The latter would be a performance hit though since the calculating the StatusPkey could get expensive.
Check out this article by Jan Kneschke... It does a great job at explaining the pros and cons of different approaches to this problem...
You can do this efficiently, but you have to do it in two queries.
First get a random offset scaled by the number of rows that match your 5% conditions:
SELECT ROUND(RAND() * (SELECT COUNT(*) FROM MyTable WHERE ...conditions...))
This returns an integer. Next, use the integer as an offset in a LIMIT expression:
SELECT * FROM MyTable WHERE ...conditions... LIMIT 1 OFFSET ?
Not every problem must be solved in a single SQL query.