I am trying to get distinct 'productnumber' ordered by the 'createdate' but at the end I need only "productnumber" sorted by 'createdate' (I cannot use top as the 'productnumber' varies in a wide flexible range).
The distinct product number is needed to be concatenated with comma (,) for e.g.
123,245,787,875 (each number represents a productnumber)
The required query looks like somewhat (this query doesn't work and gives an error The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified):
SELECT stuff(
(
SELECT distinct ',' + productnumber
FROM Product
ORDER BY createdate
FOR XML path('')
)), 1, 1, '')
Could anyone help in how to go about to get the desired result.
As Mikael Eriksson suggested, using Group By clause solved the problem. Thanks Mikael
SELECT stuff((SELECT ',' + productnumber
FROM product a
ORDER BY a.createdate FOR xml path('')),1,1,'')
AS destn_str
Related
I've a table PriceList that has a VARCHAR column tags where I store a comma separated list of values.
An example of price list is:
ID
name
tags
1
Price list 1
tag1,tag2
2
Price list 2
tag3,tag4
What I want now is to query this table passing a list of tags (comma separated values). A priceList should be selected only if all of its tags are present in the query.
The tags I pass in the query could be more than the tags defined in the PriceList's tags column.
For example:
SELECT * FROM PriceList WHERE 'tag2,tag1,tag7' IN/FIND_IN_SET??? (tags)
In this example I expect the PriceList ID1 is retrieved because all of its tags are included in 'tag2,tag1,tag7' values.
I did not find any useful function in Mysql to accomplish to what I need to do. I know this is not the best design and this is acceptable because PriceList table is really really small (5/10 items).
The only idea that came to my mind is to store tags sorted alphabetically and to see if PriceList's tag column is a substring of my tags list.
What do you think? Do you have some hint?
Have a try on the following, it splits tags in the PriceList to multiple rows and count the matching rows against the input taglist
SELECT a.ID, MAX(a.tags), MAX(a.name)
FROM (
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(p.tags, ',', comma_index), ',', -1) AS tag, p.ID, LENGTH(p.tags) - LENGTH(REPLACE(p.tags, ',', '')) + 1 AS counts, p.tags, p.name
FROM (
SELECT 1 AS comma_index
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
) a
JOIN PriceList p
WHERE a.comma_index <= LENGTH(p.tags) - LENGTH(REPLACE(p.tags, ',', '')) + 1
) a
WHERE FIND_IN_SET(a.tag, 'tag2,tag1,tag7')
GROUP BY a.ID
HAVING COUNT(*) = MAX(a.counts)
The UNION part is an example, make sure the running numbers are more than the maximum number of tags in the table.
http://sqlfiddle.com/#!9/eb379d/1
But be sure it is not a good design to concat tags while individual tags are still in use, consider to have a table store tags separately.
SELECT ifnull(LENGTH(GROUP_CONCAT(varchar SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(varchar SEPARATOR ','), ',', '')) + 1,0) AS total
FROM tablename
WHERE date(date and time)=curdate()
varchar this column contain comma separated values with this I am getting count of comma separated values in column exactly but not working for large data.
is there any solution to get count without length problem
You may be hitting limit of group_concat_max_len - that means that anything longer than (by default) 1024 chars will be truncated so you don't get all results.
Possible solution is counting items per row and summing rows counts.
SELECT SUM(ifnull(LENGTH(varchar) - LENGTH(REPLACE(varchar, ',', '')) + 1,0)) AS total
FROM tablename
WHERE date(date and time)=curdate()
That way you don't need to think about that limit at all.
Just raising group_concat_max_len is not really a viable solution because you will only hit it later.
The real solution is to get rid of comma separated lists and introduce another table where each item will be separate row. That way most counts and similar operations are simpler.
I'm using GROUP_CONCAT to build up Quartiles and am unsure how to get it working on scores created from two columns.
My GROUP_CONCAT looks like this - but at the moment is ordering on 'gst.raw_gps' when it should be ordering on the values arrived at through '(100/gst.max_gps)*gst.raw_gps'
GROUP_CONCAT(
(100/gst.max_gps)*gst.raw_gps
ORDER BY gst.raw_gps
SEPARATOR ','
)
Any advice much appreciated
Then use the expression instead of the column name:
GROUP_CONCAT((100/gst.max_gps)*gst.raw_gps
ORDER BY (100/gst.max_gps)*gst.raw_gps
SEPARATOR ','
)
I want to remove a spacial character in my query can anyone help. This is my query
select sum(value) from table_1 where id in (1, 2,);
This 1,2, is fetch from other table using sub-query.
To remove the trailing colon, you can use trim():
SELECT TRIM(TRAILING ',' FROM '1,2,');
My guess is that you want to look for individual values in the list, especially because ids don't usually contain commas.
For that, you can do:
select sum(value)
from table_1
where find_in_set(id, '1, 2,') > 0;
If the values are coming from a subquery, you would be better off using the subquery directly (in most cases). The query would be something like:
select sum(value)
from table_1
where id in (<subquery>);
You would need to modify the subquery to return a list of ids, rather than all concatenated into one field.
I have a table like:
id name
--------
1 clark_009
2 clark_012
3 johny_002
4 johny_010
I need to get results in this order:
johny_002
clark_009
johny_010
clark_012
Do not ask me what I already tried, I have no idea how to do this.
This will do it, very simply selecting the right-most 3 characters and ordering by that value ascending.
SELECT *
FROM table_name
ORDER BY RIGHT(name, 3) ASC;
It should be added that as your data grows, this will become an inefficient solution. Eventually, you'll probably want to store the numeric appendix in a separate, indexed integer column, so that sorting will be optimally efficient.
you should try this.
SELECT * FROM Table order by SUBSTRING(name, -3);
good luck!
You may apply substring_index function to parse these values -
select * from table order by substring_index(name, '_', -1)
You can use MySQL SUBSTRING() function to sort by substring
Syntax : SUBSTRING(string,position,length)
Example : Sort by last 3 characters of a String
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, -3);
#OR
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, -3,3);
Example : Sort by first 3 characters of a String
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, 1,3);
Note : Positive Position/Index start from Left to Right and Negative Position/Index start from Right to Left of the String.
Here is the details about SUBSTRING() function.
If you want to order by the last three characters (from left to right) with variable name lengths, I propose this:
SELECT *
FROM TABLE
ORDER BY SUBSTRING (name, LEN(name)-2, 3)
The index starts at lenght of name -2 which is the third last character.
I'm a little late but just encountered the same problem and this helped me.