I have a table with a date field, I need to find out which years have records and output only the list of the years e.g.( [2011,2012,2013] ), the only way I have imagined is to get all rows and then analyze in a php loop.
Does anybody knows a way to achieve this with pure SQL, or will I have to analyze the data with a php function?
SELECT DISTINCT YEAR(datecolumn) FROM yourtable
YEAR() is a MySQL function that will return the year corresponding to the current date stored in your column.
SELECT DISTINCT will return only unique values for the result of YEAR(datecolumn). More information can be found in this tutorial
If you need to output the list itself in one SQL query Linger's answer is clearly the way to go.
Try doing:
SELECT YEAR(dateColumn)
FROM yourTable
GROUP BY YEAR
You state that you want a list like [2011,2012,2013]. The following SQL Fiddle demonstrates how you can achieve such a thing in one field:
SELECT CONCAT('[', GROUP_CONCAT(MQ.MyYear), ']') AS YearsList
FROM
(
SELECT DISTINCT YEAR(MyDateField) AS MyYear
FROM MyTable
) AS MQ
In the above example I use a sub query to get all of the unique years found in the table. Then I use GROUP_CONCAT to combine them all together separating each year with a ,. Then I use CONCAT to add the brackets at the front and end of the string.
Related
i have one table collecting scores and other informations like the date and the user id. I would like to get the MAX of the current month and the other fields of the row. I'm having a problem to get the other informations since with functions we cannot get other fields.
I think i should do an inner join but i don't how to make it.
Thank you.
Your question is rather vague. But if you want one row, then the idea for the solution is order by and fetch first row only.
In standard SQL, the query would look like:
select t.*
from t
where extract(year from datecol) = extract(year from current_date) and
extract(month from datecol) = extract(month from current_date)
order by t.score desc
fetch first 1 row only;
Databases often differ on database functions. For instance, many use year() and month() functions, rather than extract(). Similarly, many databases do not support fetch first 1 row only, using limit or select top instead.
Thank you, yes it does work doing this way but the idea was to use MAX (for learning purpose).
I have scores table, with the following fields: id, score, date, user_id
I would like, using MAX, to get the best and latest score of the current month along with the other fields (ie the id, date and user_id).
I'm working on a page which displays set of data from mysql.
I wanted to know is there any way to avoid displaying a data with same name?
for example if i have 2 skills in database as PHP and php then it should only display either one of those .
Use group by in your SQL query to group the skills and appear only one.
If the column name is skill append the following line to the query
GROUP BY LOWER(skill);
Use DISTINCT keyword.
e.g SELECT DISTINCT skill FROM skills
Database is case-insenstive (at least MySQL), so php and PHP will be treated as duplicates.
Hence, the problem gets solved.
try this query
SELECT DISTINCT column_name,column_name FROM table_name;
SELECT DISTINCT col1 FROM skills
DISTINCT keyword is used to return only distinct (different) values.
This question already has answers here:
MySQL: Fastest way to count number of rows
(14 answers)
Closed 8 years ago.
I want to count all of rows in table that match to my condition as fast as mysql can do.
So, i have four SQL and want you to explain all of them, how is it different for each SQL?
and which is fastest or best for query times and server performance? or it has another way that can better than these. Thank you.
select count(*) as total from table where my_condition
select count(1) as total from table where my_condition
select count(primary_key) as total from table where my_condition
or
select * from table where my_condition
//and then use mysql_num_rows()
First of all don't even think about doing the last one! It literally means select all the data I have in the database, return it to the client and the client will count them!
Second, you need to understand that if you're counting by column name, count will not return null values, for example: select count(column1) from table_name; if there is a row where column1 is null, it will not count it, so be careful.
select count(*), select count(1), select count(primary_key) are all equal and you'll see no difference whatsoever.
This is quite difficult to explain in the title, so I'll do my best here. Basically I have a column in a MySQL products table that contains rows like:
FEL10
FEL20
FEL30
PRO05
PRO07
PRO08
VAI12
VAI13
VAI14
These are the categories ("FEL","PRO","VAI") and a identification number of my products ("10", "20" and so on). I need an SQL select query that creates me a textual array like:
FEL*
PRO*
VAI*
With this array I need to create a listbox, that allows me to choose a category (regardless of the identification number). Once I choose a category, let's say PRO*, I will need to do the reverse action: print all the products info related to PRO05, PRO07 and PRO08.
How do you think you can achieve this? I have been trying using the DISTINCT statement but I need to filter only the first characters, otherwise it will be useless. I also tried the SUBSTRING() and LEFT() functions, but they seem not to be working (I get an SQL Syntax error).
--
Thanks for your help as always
What is wrong with?
SELECT distinct left(col, 3) as category FROM `table1`
MySQL LIKE to the resque:
SELECT col1 FROM table1 WHERE col1 LIKE 'FEL%';
This way you have to add all cases using OR.
Alternative - REGEXP:
SELECT col1 FROM table1 WHERE col1 REGEXP '(FEL|PRO|VAI).*'
Then it's just a matter of writing proper regex.
I would use extra col to group your items - to avoid such selecting altogether (which should be quite expensive on bigger dataset).
https://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
To get the list of the 3-letter codes use:
select distinct left(combicode, 3)
from mytable;
When a user selects one of the values use this to get all matching entries:
select *
from mytable
where combicode like concat(#category, '%');
(Aside from that: It's a bad idea to have concatenated values in one column. Why not have one column for the category and another for the product code? Then there would be no problem at all.)
Yes, there's a thousand questions about this on SO, but I've been searching for half an hour and I've yet to find a solution.
So, I've a table like this:
And this is my query:
SELECT DISTINCT rengasID,leveys FROM renkaat ORDER BY leveys ASC
And this is the result I get:
If you get the idea, I'm populating a select field with it, but it still has duplicates.
What am I doing wrong?
If you want distinct leveys, just choose that field:
SELECT DISTINCT leveys
FROM renkaat
ORDER BY leveys ASC
The rengasid has a different value on each row.
The distinct clause applies to all the columns being returned, regardless of parentheses.
EDIT:
If you need the regasid in the result, then use group by:
select leveys, min(regasid) as regasid
from renkaat
group by leveys
order by leveys asc;
This gives the first id. If you need all of them, you can get them in a list using group_concat(). If you need a separate id on each row, well, then you have duplicates.
Your rengasID is still different in each shown line. The distinct will check a mix of every selected field, so in this case it will search a distinct combination of rengasID and leveys.
You cannot ask for your ID here, since MySQL has no way of knowing which one you want.
Depending on what you want to do it can be more correct to save your "leveys" (I'm not sure what they are) in a separate table with a unique ID and join it. For filling up your list with all possible leveys, you can just query that new table.
This can be important because using group by, you can get random results for id's later on.
This is because you are selecting combination of rengasID and leveys. And what you are getting as a result is a distinct combination of the two.
To achieve what you are trying, see the answer of #GordonLinoff.