how to convert values in a set/Enum into integers mysql - mysql

I have a database with this table(rating)..
+---------+-------------+----------+------+------------+
| rate_id | reviewer_id | movie_id | rate | date1 |
+---------+-------------+----------+------+------------+
| 1 | 201 | 101 | 2 | 2011-01-22 |
| 2 | 201 | 101 | 4 | 2011-01-27 |
| 3 | 202 | 106 | 4 | NULL |
| 4 | 203 | 103 | 2 | 2011-01-20 |
| 5 | 203 | 108 | 4 | 2011-01-12 |
| 6 | 203 | 108 | 2 | 2011-01-30 |
| 7 | 204 | 101 | 3 | 2011-01-09 |
| 8 | 205 | 103 | 3 | 2011-01-27 |
| 9 | 205 | 104 | 2 | 2011-01-22 |
| 10 | 205 | 108 | 4 | NULL |
| 11 | 206 | 107 | 3 | 2011-01-15 |
| 12 | 206 | 106 | 5 | 2011-01-19 |
| 13 | 207 | 107 | 5 | 2011-01-20 |
| 14 | 208 | 104 | 3 | 2011-01-02 |
+---------+-------------+----------+------+------------+
the rate is a set which has those values
('1','2','3','4','5'). i want to convert this set values to integers. i used cast(rate as unsigned) .then i used this query..
SELECT rate,cast(rate AS UNSIGNED) FROM rating;
it gives me this table
mysql> SELECT rate,cast(rate as unsigned) FROM rating;
+------+------------------------+
| rate | cast(rate as unsigned) |
+------+------------------------+
| 2 | 2 |
| 4 | 8 |
| 4 | 8 |
| 2 | 2 |
| 4 | 8 |
| 2 | 2 |
| 3 | 4 |
| 3 | 4 |
| 2 | 2 |
| 4 | 8 |
| 3 | 4 |
| 5 | 16 |
| 5 | 16 |
| 3 | 4 |
+------+------------------------+
it looks like binary values..plz help me to convert this into correct integer values..

Try this..
CAST (CAST(rate AS char) AS UNSIGNED);
it works..

ENUM is not a good selection for number values. instead of using ENUM you can use TYNYINT and filter values for only accept [1-5] in your code.
MYSQL document mention that clearly
We strongly recommend that you do not use numbers as enumeration values, because it does not save on storage over the appropriate TINYINT or SMALLINT type, and it is easy to mix up the strings and the underlying number values (which might not be the same) if you quote the ENUM values incorrectly. If you do use a number as an enumeration value, always enclose it in quotation marks. If the quotation marks are omitted, the number is regarded as an index. See Handling of Enumeration Literals to see how even a quoted number could be mistakenly used as a numeric index value.
Check this out : MYSQL DOC Enumeration Limitations
:)

You should try with this following ways.
The type for the result can be one of the following values:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
Thanks.

Related

MYSQL adding columns value of rows

I have a problem in which I have a STUDENT table as
+-------------+-------------+-------------+-------------+---------------+
| roll_number | name | subject_one | subject_two | subject_three |
+-------------+-------------+-------------+-------------+---------------+
| 1 | Sheila | 32 | 48 | 64 |
| 2 | Rachel | 24 | 21 | 25 |
| 3 | Christopher | 55 | 12 | 10 |
+-------------+-------------+-------------+-------------+---------------+
I want the print the output as
+-------------+-------------+-------------+
| roll_number | name | total |
+-------------+-------------+-------------+
| 1 | Sheila | 144|
| 2 | Rachel | 70 |
| 3 | Christopher | 77 |
+-------------+-------------+-------------+
and select all student having marks greater than 75 ??
How can I achieve this using MYSQL ??
I think you just need the aggregate functions and using them is enough. I am not sure if it can help you or not.
SELECT roll_number , name , (subject_one + subject_two + subject_three) AS total FROM STUDENT HAVING total > 75 ;

Where and group conflict?

I have a table like this:
mysql> select * from studentscore;
+------------+-----------+-------+
| student_id | cource_id | score |
+------------+-----------+-------+
| 1 | 1 | 80 |
| 1 | 2 | 90 |
| 1 | 3 | 85 |
| 1 | 4 | 78 |
| 2 | 2 | 53 |
| 2 | 3 | 77 |
| 2 | 5 | 80 |
| 3 | 1 | 71 |
| 3 | 2 | 70 |
| 3 | 4 | 80 |
| 3 | 5 | 65 |
| 3 | 6 | 75 |
| 4 | 2 | 90 |
| 4 | 3 | 80 |
| 4 | 4 | 70 |
| 4 | 6 | 95 |
| 5 | 1 | 60 |
| 5 | 2 | 70 |
| 5 | 5 | 80 |
| 5 | 6 | 69 |
| 6 | 1 | 76 |
| 6 | 2 | 88 |
| 6 | 3 | 87 |
| 7 | 4 | 80 |
| 8 | 2 | 71 |
| 8 | 3 | 58 |
| 8 | 5 | 68 |
| 9 | 2 | 88 |
| 10 | 1 | 77 |
| 10 | 2 | 76 |
| 10 | 3 | 80 |
| 10 | 4 | 85 |
| 10 | 5 | 83 |
| 11 | 3 | 80 |
| 12 | 4 | 99 |
| 13 | 5 | 74 |
+------------+-----------+-------+
I want to show student_id and students' average scores that are higher than 80.
The output I want is like this:
+------------+-------------------+
| student_id | Average |
+------------+-------------------+
| 1 | 83.25 |
| 4 | 83.75 |
| 6 | 83.66666666666667 | // and how can I make this result shorter like 83.67?
| 7 | 80 |
| 9 | 88 |
| 10 | 80.2 |
| 11 | 80 |
| 12 | 99 |
+------------+-------------------+
I've tried the following codes
mysql> select student_id, avg(score) as average_score
-> from studentscore
-> group by student_id
-> where avg(score) >= 80;
and it gave me an syntax error.
I know by rules the where clause should go before the group by clause but I can't because the where clause depends on the result from the group by clause, and if I switch their position it will give me another error("Invalid use of group function").
Can some one tell me how to get the table I want?
use "having" instead of "where"
use having instead of where.
Here's the difference:
with where you can write a predicate that will be applied to each row
with having you can write a predicate that will applied to each group
and in your case, the 2nd is the only solution that can work.
select student_id, avg(score) as average_score
from studentscore
group by student_id
having avg(score) >= 80;
where applies a filter to your data before grouping has taken place, whereas having applies a filter post-grouping. round(,2) will format as you also ask:
select student_id, round(avg(score), 2) as average_score
from studentscore
group by student_id
having average_score >= 80;

MySQL get multiple rows into columns

I have a table called visits where concat(s_id, c_id) is unique and id is the primary key. s_id is the ID number of a website and c_id is a campaign ID number. I want to show all the hits each campaign is getting and group by the site. I want each site on a single row
+-----+------+------+------+
| id | s_id | c_id | hits |
+-----+------+------+------+
| 1 | 13 | 8 | 245 |
| 2 | 13 | 8 | 458 |
| 3 | 13 | 3 | 27 |
| 4 | 13 | 4 | 193 |
| 5 | 14 | 1 | 320 |
| 6 | 14 | 1 | 183 |
| 7 | 14 | 3 | 783 |
| 8 | 14 | 4 | 226 |
| 9 | 5 | 8 | 671 |
| 10 | 5 | 8 | 914 |
| 11 | 5 | 3 | 548 |
| 12 | 5 | 4 | 832 |
| 13 | 22 | 8 | 84 |
| 14 | 22 | 1 | 7 |
| 15 | 22 | 3 | 796 |
| 16 | 22 | 4 | 0 |
+----+------+------+-------+
I would like to have the following result set:
s_id | hits | hits | hits| hits
13 | 245 | 458 | 27 | 193
14 | 320 | 183 | 783 | 226
5 | 671 | 914 | 548 | 832
22 | 84 | 7 | 796 | 0
Here is what I have tried which does not pull all the hits columns back.
SELECT v.*, v2.* FROM visits v
INNER JOIN visits v2 on v.s_id = v2.s_id
GROUP BY s_id
How can I get multiple rows into columns?
If your'e data set is not crazy huge and you are just trying to get the multiple rows as a single row.... one way to do this...
SELECT
s_id,
GROUP_CONCAT(hits SEPARATOR ',') as hits_list
FROM
visits
GROUP BY s_id
Since it doesn't use any joins or subqueries etc, i find this way to be quite fast.
you can later split/explode the data based on the ',' separator in PHP or whatever language you are using.
$hits = explode($hits_list, ','); //get them in an array

MySQL Pivot Handling Values

I have a table like the one bellow:
+------+------+------+-------+
| pkey | name | exam | score |
+------+------+------+-------+
| 1 | Bob | Math| 75 |
| 2 | Bob | Eng | 77 |
| 3 | Bob | Phy | 78 |
| 4 | Sue | Math| 80 |
| 5 | Sue | Eng | 90 |
| 6 | Sue | Phy | 97 |
| 7 | Suzy | Math| 98 |
| 8 | Suzy | Eng | 99 |
| 9 | Suzy | Phy | 99 |
+------+------+------+-------+
And I want to make a query to pivot it into:
+------+------+------+-------+
| Name | Math | Phy | Eng |
+------+------+------+-------+
| Bob | 75 | 78 | 77 |
| Sue | 80 | 97 | 90 |
| Suzy| 90 | 99 | 99 |
+------+------+------+-------+
The problem is, the discipline of the exam can have like 500 different values and I can't define them all as they might change eventually and start having 600 different ones instead.
Is it possible to create a query that will read the value of the exam and create a new column to display the values of it?
Say for example they add Hist to the values of exam and say Suzy got a 100, it would then be like this:
+------+------+------+-------+-----+
| Name | Math | Phy | Eng | Hist|
+------+------+------+-------+-----+
| Bob | 75 | 78 | 77 | |
| Sue | 80 | 97 | 90 | |
| Suzy| 90 | 99 | 99 | 100 |
+------+------+------+-------+-----+
Thanks in advance
A SQL query has to have a well-defined set of columns. You can do what you want with a prepare statement and dynamic SQL.
Another approach would be to create a string of the possible values, such as Math:75, Phy78, Eng:77. If this works for you:
select name, group_concat(exam, ':', score separator ', ')
from table t
group by name;

MySQL Query for averages

good morning. I have this table:
mysql> select * from Data;
+---------------------------+--------+-------+
| affyId | exptId | level |
+---------------------------+--------+-------+
| 31315_at | 3 | 250 |
| 31324_at | 3 | 91 |
| 31325_at | 1 | 191 |
| 31325_at | 2 | 101 |
| 31325_at | 4 | 51 |
| 31325_at | 5 | 71 |
| 31325_at | 6 | 31 |
| 31356_at | 3 | 91 |
| 31362_at | 3 | 260 |
| 31510_s_at | 3 | 257 |
| 5321_at | 4 | 90 |
| 5322_at | 4 | 90 |
| 5323_at | 4 | 90 |
| 5324_at | 3 | 57 |
| 5324_at | 4 | 90 |
| 5325_at | 4 | 90 |
| AFFX-BioB-3_at | 3 | 97 |
| AFFX-BioB-5_at | 3 | 20 |
| AFFX-BioB-M_at | 3 | 20 |
| AFFX-BioB-M_at | 5 | 214 |
| AFFX-BioB-M_at | 7 | 20 |
| AFFX-BioB-M_at | 8 | 40 |
| AFFX-BioB-M_at | 9 | 20 |
| AFFX-HSAC07/X00351_M_at | 3 | 86 |
| AFFX-HUMBAPDH/M33197_3_st | 3 | 277 |
| AFFX-HUMTFFR/M11507_at | 3 | 90 |
| AFFX-M27830_3_at | 3 | 271 |
| AFFX-MurIL10_at | 3 | 8 |
| AFFX-MurIL10_at | 5 | 8 |
| AFFX-MurIL10_at | 6 | 4 |
| AFFX-MurIL2_at | 3 | 20 |
| AFFX-MurIL4_at | 5 | 78 |
| AFFX-MurIL4_at | 6 | 20 |
| U95-32123_at | 1 | 128 |
| U95-32123_at | 2 | 128 |
| U98-40474_at | 1 | 57 |
| U98-40474_at | 2 | 57 |
+---------------------------+--------+-------+
37 rows in set (0.00 sec)
If I wanna look for the average expression level (level) of each array probe (affyId) across all experiments, I do SELECT affyId, AVG(level) AS average FROM Data GROUP BY affyId;
However, I can't figure out how to look for the average expression level of each array probe (affyId) for each experiment... It must be something similar to the last query, but I don't obtain good results... any help?
PD: someone told me I should give some reputation or click to some green button if somebody solves my question... Is it right? How do I do it? I'm pretty new on this website...
This shows the average for every affyId:
SELECT affyId, AVG(level) AS average FROM Data GROUP BY affyId
This the average for every exptId:
SELECT exptId, AVG(level) AS average FROM Data GROUP BY exptId
and this the average for every exptId in every affyId:
SELECT affyId, exptId, AVG(level) AS average FROM Data GROUP BY exptId, affyId
Just add that to the group by clause
SELECT affyId, exptId, AVG(level) AS average
FROM Data
GROUP BY affyId, exptId;