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.
Related
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
could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference
could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference
I have a table which has only 3 columns. When I type the following query
select * from MyTable order by 5 and 2;
I get every thing in the table( The result is equal to that of select * from MyTable; ). What I originally expected is that I would get some kind of error. But I didn't get it, why?
order by 5 and 2 is interpreted as order by (5 and 2) which is a constant expression, hence no real ordering is done and data is simply shown in the order it was inserted.
What is happenning here is that 5 and 2 is seen as an expression which is evaluated to 1. However, it shouldn't give a result sorted by first column.
Actually, I think you only get sorted data because you inserted it in sorted sequence. Take a look at this SQLFiddle:
http://sqlfiddle.com/#!2/3e04e/1
The data is not sorted by any of the columns, it is being sorted by a value 1.
5 and 2 are column indexes and they mean 5th column and 2nd column.
select * from MyTable order by 5,2;
It means start with index 5 and bring 2record i.e 5,6,7
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