Making a column based on the order of another column - mysql

I have a table called cars with a bunch of columns.
I want to make a column called "Make_ID" that will increment based on the alphabetical order or a column "Make".
My goal is to give each Make String a unique integer such as that wherever I have a record with a Make of "Ford", that Make_ID will always be, for example, the number 3 or if I have a Make of "Mazda" that Make_ID number will be 15 for ever record that has a Make of Mazda.
Is there a way to this?

If you have the data and just want this in a result set, then use dense_rank():
select c.*, dense_rank() over (order by make) as make_id
from cars c

Related

Select all column but distinct on one column and random

I have the following table:
ID Type Name
1 1 first value
2 1 2nd value
3 2 3rd value
I want to select a row with random Name for each Type. If I use a select with group by Type, it returns two rows, always (first value, 3rd value), but I want to make it random: sometimes first value and sometimes 2nd value. Is there any way to achieve this?
Well, your result is "random" in regards to that you cannot rely on always getting the same result. MySQL just gives you some "random" value for name. However, in order to get some value they just go through the table and pick what they see first or last, so as long as the table doesn't change, the result won't change either.
Knowing so, simply change the rows' order first:
select type, name
from
(
select type, name
from mytable
order by rand()
) randomly
group by type;
SQL fiddle: http://www.sqlfiddle.com/#!2/31560/7.

Divide result of one query on result of another query

I have a table which has 3 columns (name, course, grade).
My 'name' column contains three students.
I need to sum grades of every student and divide it by the amount of grades.
I'm trying to do something like this,
SELECT
name
FROM
table
GROUP BY
name
AND
(SELECT SUM(grade) FROM table / SELECT COUNT(grade) FROM table GROUP BY name)
I'm not a native english speaker, so I hope you understand me.
I expect you want to calculate the average grade?
SELECT name, AVG(grade)
FROM `table`
GROUP BY name
your table design does not follow the 1st rule of normalization: atomicity. You have multiple names in single column AND you want to process them separately. This makes querying more difficult and inefficient. You need to normalize your table.

automatically Generate unique id for characters mysql

I want to create a mysql table with three columns id , name, name_id,
The thing that i want to acheive is whenever user enters a name into database
then system should generate a unique id for name automatically.
e.g.
name is JJ then name_id should be 1 and if name is DD then name_id should be 2
also if name JJ is repeated in database then name_id should be 1.
The number_id values should be assign according to name sorting
i.e A should get 1 and B should get 2.
How this can be achieved by sql script or triggers ?
What about the following?
INSERT INTO tbl (name,name_id)
SELECT newname, COALESCE((SELECT name_id FROM tbl WHERE name=newname ),
(SELECT max(name_id)+1 FROM tbl))
This is assuming that column id takes care of itself, i.e. is auto_incremented.
newname can of course also be a string constant which you will have to work in to your command.
The command above works best when used for indiviual inserts ("by a user"). If you want to carry out a bulk import then it can be quite costly since for each new value the table tbl will be scanned twice. For this case a different logic should be applied:
First find all name-name_id pairs by means of a grouped select and then INNER JOIN the results with the import list. For the remaining items (without existing name_ids) do the following: find out the highest #i=max(name_id) of all records and then import the sorted list with an autonumbering mechanism (#i:=#i+1) for name_id in place ...
create a sql function that returns the name
_id upon passing name as a parameter. one way would be to add all the characters but that wont do because different arrangement of same characters would give the same sum for different names.may be concatenating primary index at the end of sum would do the job. i think you can define a suitable logic in a sql function to achieve the results.

MySQL Subquery - Returning More Than One Row

I have a table in which there are a listing of names, first and last in a column. So a column, called "manager" could have a value of "John Doe". I want to right a query that simply goes through each row in this table and displays the first letter and last name of the "manager" column. Everything I do comes up with "Subquery returns more than one row".
Starting small, I've just decided to pull the first letter:
SELECT id, LEFT((SELECT manager FROM my_table), 1) FROM my_table;
Or am I just completely off base on this
You're using a subquery to fetch into a field of a parent query. As such, the subquery can return only a single row. think of it this way: a result set is a 2-dimensional construct. a series of columns and rows. The data a subquery returns has to match the physical constraints of the thing it's returning into.
Since you're fetching into a field, that means one SINGLE value. If multiple values were allowed to be returned, you'd effectively be trying to turn your 2D result set into a 3d set (rows + columns plus a skyscraper growing out of one of those fields).
Your query does NOT need to be a subquery at all:
SELECT id, LEFT(manager, 1) AS first_letter FROM yourtable
Also, not that if you want separate first and last names, you would be better off storing those are separate fields. It is very easy to rebuilt a name from a set of first/last name fields, but very very difficult to reliably separate a monolithic name into individual first and last names, e.g.
simple:
John Doe (fn: john, ln: doe)
hard:
Billy Jo Todd (is that "Billy" and "Jo Todd", "Billy" and "Todd" with middle name Jo?
dead simple:
field firstname = John
field lastname = Doe
If you want to use a subquery, this query works as you intend it to, though I am not sure this is the best way to proceed in any case. We would need more information about your needs to assert that.
SELECT
m1.id,
m2.manager
FROM
my_table AS m1 INNER JOIN
(SELECT id, LEFT(manager, 1) AS manager FROM my_table) as m2
ON m1.id = m2.id
http://sqlfiddle.com/#!2/9c395/6
You must add a condition to your subquery to return the row you want to compare like
SELECT manager FROM my_table WHERE id = 1

MS Access 2003 - ordering the string values for a listbox not alphabetical

Here is a silly question. Lets say I have a query that produces for a list box, and it produces values for three stores
Store A 18
Store B 32
Store C 54
Now if I ORDER BY in the sql statement the only thing it will do is descending or ascending alphabetically but I want a certain order (only because THEY WANT A CERTAIN ORDER) .....so is there a way for me to add something to the SQL to get
Store B
Store C
Store A
i.e. basically row by row what i want. thanks!
Add a numeric field, sequencer, to the table which contains the store names. Use the sequencer values to determine your sort order.
SELECT sequencer, store_name FROM YourTable ORDER BY sequencer;
In the list box, set the column width = 0 for the sequencer column.
Or simply, as #dscarr suggested, don't include sequencer in the SELECT field list, but just include it in the ORDER BY ...
SELECT store_name FROM YourTable ORDER BY sequencer;
You can do 1 of 2 things.
Either use a SWITCH stament, something like
SELECT Table1.Store,
Table1.Val,
Switch([Store]="StoreB",1,[Store]="StoreC",2,[Store]="StoreA",3) AS Expr1
FROM Table1
ORDER BY Switch([Store]="StoreB",1,[Store]="StoreC",2,[Store]="StoreA",3);
Or use a secondary order table, that stores the values of the store names, and an order by value.