select distinct values of a replaced selected result - mysql

Good day all.
I'm facing a little problem with a mySql query. let's assume we have a table with a coulmn in which the values are pairs, but unified in the same field, so something like this:
id | serviceName
----+-------------
1 | foo - bar
2 | foo - doo
3 | foo - tep
4 | bee - bar
5 | bee - blo
I would like to select distinct the first part of serviceName, in this case foo, bee.
the desired output should be:
foo
bee
in the resultset.
what I've thought right now is something about making a SELECT DISTINCT a FROM REPLACE ( (SELECT serviceName as a FROM tableName), ' - ***', '')
but i'm not really sure if it is possible, and how to make it. I only would like to select the first part of the field, and I would like to take only distinct vlaues of it... it is possible? I need a right direction pointing,, I can make researches by my self.
thanks in advance.

Assuming that you always want to split on a dash -, this should work for you.
SELECT DISTINCT LEFT(serviceName, LOCATE('-', serviceName) - 2) FROM tableName;
SQLFiddle

IS this what you are looking at ?
select substring_index(serviceName,'-',1) as `first_part`
from test
group by `first_part`
DEMO

Related

Select similar records from mysql

I have a database as shown below
ID color number code
102966 red 1 9f6606069f9b999b
102968 red 1 9f6606069f9b999b
102967 red 1 9f0606069f9f9f9f
102969 red 1 9f0606069f9f9f9f
103630 red 1 bbff9f0f8fdc9f7e
101582 red 1 bbff9b0fcf9f99d9
102000 red 1 99fd9f0fab999fff
101603 red 1 bbff9f0d8f9d96df
102016 red 1 bbff9900c09999df
This table has more then 4000 entries.
I got this output by using
Select * from mytable order by code asc
Now I want output as a Id-Id-Id.... where code is similar.
So for given snippet it should come like
102966-102968
102967-102969
So I want like that those records are similar, their code should come like this.
Please help.
I don't really see what your last result row is about, it might be a mistake or I don't understand what you need
I think you are looking for a group_concat
select group_concat(ID ORDER BY ID SEPARATOR '-' ) AS dup
from mytable
GROUP BY code
HAvING count(*) >1
ORDER BY dup
Results:
| dup |
|---------------|
| 102966-102968 |
| 102967-102969 |
A group_concat shows all the values matching the GROUP BY, here the ID values.
The term SEPARATOR is there to specify - as separator between your IDs, because the default separator is ,
If you want all rows, even those for which there are no duplicate code, remove the having clause
SQL Fiddle
the last answer from #Thomas G is correct but if you want to have it in the correct order use:
select CONCAT(MIN(ID),'-',MAX(ID))
from mytable
GROUP BY code
HAvING count(*) >1

SQL stament groups rows and calculate average

I am stuck with the following issue. I have 1 table that looks like this:
field_number.. Value
````````````````````````````````
1 ......................... 1
2 ..........................1
3 ......................... 2
4 ..........................2
etc.
I want to group different fieldnumbers and have an average for the value column. So the output should be:
field_number................Value
name(1,2)...................... 1.............. ((1+1)/2)
name(3,4)...................... 2.............. ((2+2)/2)
I have checked previous questions but cannot find any question that covers this issue (I might search on the wrong keywords though). So if this has already been covered my appologies, but any help or a point to a previous answer would be appreciated.
** =============UPDATE============= **
I went through your suggestions but did not get it right. So I am trying to be more specific. I almost have the result I want apart from the fact I want to have a fixed value in one of my columns. I have the following query:
Select
Avg(wp_rg_lead_detail.value),
wp_rg_lead_detail.field_number,
From
wp_rg_lead_detail
Where
wp_rg_lead_detail.field_number In (15, 17, 24) A
UNION
Select
Avg(wp_rg_lead_detail.value),
wp_rg_lead_detail.field_number,
From
wp_rg_lead_detail
Where
wp_rg_lead_detail.field_number In (16, 108, 18)
etc.
This gives me a table with two columns
wp_rg_lead_detail.value................field_number
4.3 (average)..............................15 (first value of av calculation)
What I want is to change the field number (15 in this case) in a fixed value (text). What and how should I add this to the query?
SELECT avg(value) FROM table WHERE field_number in (1,2)
SELECT avg(value) FROM table WHERE field_number in (3,4)
If your table is really this simple, you can also get away with:
select distinct
Value,
count(Value) as '#'
from table_name
group by Value
If you acctually want to group by a range, than you can put the logic of the range in your grouping clause (see this fiddle)
select distinct
avg(Value) as average,
floor(Value),
count(Value) as '#'
from table_name
group by floor(Value)
In the fiddle I used grouping on whole integers, but you can make that as complex as you like (see, for instance, this example)
If you are actually also interested in your corresponding fields, use group_concat() like so
select
Value,
group_concat(
distinct field_number
order by Value
) as fields
from table_name tn1
group by Value
order by Value
output:
Value | fields
---------------------------------
1 | 1,2
2 | 3,4
See this fiddle implemented from this blog post
For a generalized answer.
SELECT CONCAT('name','(',GROUP_CONCAT(field_number),')') AS field_number,
AVG(Value) as Value
FROM table_name
group by table_name.`Value`
Hope this helps.

select concat with in-Tag

How can I form the following statement in MySql, that it will work?
select a,b,c from xx where a in concat(select y from abc where x='a','%');
Notice: The subquery returns more than one line!
Example
|---A----|
|/backup/|
|/foto/ |
And the a in concat should return all items where the subquery is like the following example:
|/backup/23/x.txt |
|/backup/xx/asdf |
|/backup/x.txt |
That's the reason why I need the concat!
It is difficult to tell exactly what you are after here because your example data appears to contradict your question, but I think you need to use the EXISTS clause, rather than IN:
SELECT a, b, c
FROM xx
WHERE EXISTS
( SELECT 1
FROM abc
WHERE abc.x = 'a'
AND xx.a LIKE CONCAT(abc.y, '%')
);
Example on SQL Fiddle

Sql Select into array - column has seperater

I have a column in my DB that has the following data (yeah i know its wrong to have multiple names separated by some random character)
"John Cusack | Thandie Newton | Chiwetel Ejiofor"
I want to be able to separate these people into an array to use later or even just to be able display them like below will help
John Cusack
Thandie Newton
Chiwetel Ejiofor
any ideas please
thanks in advance
As you say, storing delimited lists in an RDBMS really is not a good idea; however, you may be able to use MySQL's string manipulation functions such as SUBSTRING_INDEX() to obtain your desired results (MySQL doesn't have array types, so I assume you're merely looking to split the data):
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(my_column, '|', 1), -1),
SUBSTRING_INDEX(SUBSTRING_INDEX(my_column, '|', 2), -1),
SUBSTRING_INDEX(SUBSTRING_INDEX(my_column, '|', 3), -1)
FROM my_table
Note that one doesn't actually need to invoke SUBSTRING_INDEX() twice for the first and last elements of the list, but I thought it informative to do so in order that the pattern for further elements can be seen more clearly.
If you were so inclined, you could build a stored procedure that loops over the string populating a temporary table with each found element—but this is all so far away from "good practice" that it's almost certainly not worth delving into it any further.
you can try this.
select substring_index(substring_index('a|b|c|h', '|',#r:=#r+1),'|',-1) zxz
from (select #r:=0) x,
(select 'x' xx union select 'v' xx union select 'z' xx union select 'p' xx) z;
Result looks like
----
|zxz|
-----
|a |
------
|b |
------
|c |
------
|h |
------
locatet here: Mysql
and a little modified.
Remember: The "count" of the union statements have to be the same as your delemiter.
Kind Regars

Using concat in where conditions, good or bad?

A simple quiz:
Probably many guys know this before,
In my app there is a query in which Im using concat in where condition like this,
v_book_id and v_genre_id are 2 variables in my procedure.
SELECT link_id
FROM link
WHERE concat(book_id,genre_id) = concat(v_book_id,v_genre_id);
Now, I know there is a catch/bug in this, which will occur only twice in your lifetime. Can you tell me what is it?
I found this out yesterday and thought I should make a noise about all others practicing this.
Thanks.
Let's have a look
WHERE concat(book_id,genre_id) = concat(v_book_id,v_genre_id);
as opposed to
WHERE book_id = v_book_id AND genre_id = v_genre_id;
There. The second solution is
faster (optimal index usage)
easier to write (less code)
easier to read (what on earth was the author thinking to concatenate numbers???)
more correct (as Alnitak also stated in the question's comments). check out this sample data:
book_id | genre_id
1 | 12
11 | 2
Now add (or concat) v_book_id = 1 and v_genre_id = 12 and see how you'll get funny results with your concat() query
Note, some databases (including MySQL) allow operations on tuples, which may be what the clever author of the above really intended to do:
WHERE (book_id, genre_id) = (v_book_id, v_genre_id);
A working example of such a tuple predicate:
SELECT * FROM (
SELECT 1 x, 2 y FROM DUAL UNION ALL
SELECT 1 x, 3 y FROM DUAL UNION ALL
SELECT 1 x, 2 y FROM DUAL
) a
WHERE (x, y) = (1, 2)
Note, some databases will need extra parentheses around the right-hand side tuple : ((1, 2))