Grouping mysql by a regex? - mysql

I am trying to find the count of how many times a location is used in my table of search results, but I want to group together cases where the same post code area start is used. The following groups purely on the text used:
SELECT count(*),
search_browse_log.postcode_start
FROM search_browse_log
GROUP BY postcode_start
ORDER BY count(*) DESC
But in the data, I have for example CR0, CR1, CR2 (postcode starts). I want to group them all together so I have a count of 3 for "CR", rather than 1 each of CR0, CR1 and CR2.
Thanks in advance if you can help!

Use a conditional in the GROUP BY clause to get either 1 or 2 characters, depending on whether the postcode starts with 1 or 2 letters.
GROUP BY IF(postcode_start REGEXP '^[A-Z][A-Z]',
LEFT(postcode_start, 2),
LEFT(postcode_start, 1))

If it's only the first 2 characters of the postcode, you could use the LEFT function in the group by:
SELECT count(*),
LEFT(postcode_start,2) as `postcode_start`
FROM search_browse_log
GROUP BY LEFT(postcode_start,2)
ORDER BY count() DESC
To group by the non-numeric characters at the start of the string:
SELECT count(*),
IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2)) as `postcode_start`
FROM search_browse_log
GROUP BY IF(postcode_start REGEX '^[a-ZA-Z][0-9]',LEFT(postcode_start,1),LEFT(postcode_start,2))
ORDER BY count() DESC
For reference, see https://dev.mysql.com/doc/refman/5.7/en/regexp.html#operator_regexp

Related

Select with match and order by date and then relevance?

Im using the below to select from 3 columns and it works as it should but when I try to add date to order by then I can´t get it right. Its a mysql database.
SELECT *,
MATCH(artikel) AGAINST ("&soktexten&" IN BOOLEAN MODE)* 10 as rel1,
MATCH(ingress) AGAINST ("&soktexten&" IN BOOLEAN MODE) as rel2,
MATCH(texten) AGAINST ("&soktexten&" IN BOOLEAN MODE) as rel3
FROM produkt
WHERE MATCH (artikel, ingress, texten) AGAINST ("&soktexten&" IN BOOLEAN MODE)
ORDER BY (rel1)+(rel2)+(rel3) DESC LIMIT 25;
I have 3 rows where the "artikel" has the following text and then the date .
Row 1 - "Träbord" - "2019-01-01"
Row 2 - "Träbord aaa" - "2019-01-02"
Row 3 - "Träbord bbb" - "2019-01-03"
I want it to search for the latest date where the matching word is in "artikel".
So if I search for "Träbord bbb" or "Träbord aaa" it is showing them on top of the list as they should, but if I search for only "Träbord" it is showing "Träbord" as the first one in the list and I want it to search for the latest date first, then the matching word.
So how do I change ORDER BY (rel1)+(rel2)+(rel3) DESC LIMIT 25 so it order by date first and then by the matching word?
I have tested with several variants of ORDER BY (rel1)+(rel2)+(rel3), date DESC LIMIT 25 etc but I can´t get it right.
Any input really appreciated, thanks.
I think this does what you want:
ORDER BY (rel1 + rel2 + rel3) > 0 DESC, -- put matches first
date DESC

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.

MySQL MAX from count query

I have table rozpis_riesitelov which contains columns :
id_rozpisu_riesit, id_zam, id_projektu, id_ulohy.
I made query :
select id_zam, id_ulohy, count(*) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)
which shows me id of employee (id_zam) and how many times He was in project (id_ulohy is irrevelant but I had to select it beacuse of having clause). It shows me everyone in db but I am looking for employee with ID of 4 who is in 6 projects (Yes, I could do order by but I want to see max). When I do max of this query like this:
select max(counted)
from (select id_zam, id_ulohy, count(id_zam) as counted
from rozpis_riesitelov
group by id_zam
having id_ulohy in (1,2,8)) as riesitel
which shows me number 149 instead of 6.
So basically I only need to find employee that occurs in the most of the projects.
What's wrong with sorting by the COUNT() value, and limiting to one result?
SELECT `id_zam`,
`id_ulohy`,
COUNT(*) AS `counted`
FROM `rozpis_riesitelov `
WHERE `id_ulohy` IN ( 1, 2, 8 )
GROUP BY `id_zam`
ORDER BY `counted` DESC
LIMIT 1
Not sure exactly what you are trying to accomplish but you only use HAVING to filter on your aggregate like this:
HAVING COUNT(*) > 1
you should be able to move the condition to a WHERE clause and get correct max returned:
select max(counted)
from (select id_zam, count(id_zam) as counted
from rozpis_riesitelov
where id_ulohy in (1,2,8)
group by id_zam) as riesitel

Sql query to sum up total of columns previously used aggregate function

From this post, enter link description here
I would like to improve the query
SELECT `BetType`,
count(`BetType`) AS COUNT,
sum(`BetAmount`) AS BetAmountTotal,
sum(`Payout`) AS PayoutTotal
FROM `betdb`
LEFT JOIN `matchdb` ON `betdb`.`MatchID` = `matchdb`.`MatchID`
WHERE `betdb`.`MatchID`=135
GROUP BY `BetType`
thanks to Sadikhasan, who helped on this query
I would like to add another row showing the totals of the columns
BetType Count BetAmount Total Payout Total
Handi 2 60000 950000
Homerun Count 4 10000 0
Total 6 70000 950000
this seems to be needing another SELECT statement but how would I put another row explicitly showing the "Total" string and getting the sum of the previously used columns with Aggregate Functions?
You can use WITH ROLLUP modifier to GROUP BY, which will give you another row with totals, but the column you group on (BetType) will show NULL for that row. But nothing stops you from using COALESCE() to replace that NULL with 'Total' string.
SELECT COALESCE(`BetType`,'Total') AS BetType,
COUNT(*) AS `Count`,
sum(BetAmount) AS BetAmountTotal,
sum(Payout) AS PayoutTotal
FROM betdb
WHERE betdb.MatchID=135
GROUP BY BetType WITH ROLLUP

mysql query - pairs of repeating numbers

I have a database with 2 columns (ex: no_1, no_2) and then 5000 rows of data, numbers are between 1 - 20 , I need to find a pairs of numbers which where repeating the most of the times?
Any help please ?
Something like this maybe:-
SELECT no_1, no_2, COUNT(*) AS numbercount
FROM SomeTable
GROUP BY no_1, no_2
ORDER BY numbercount DESC