How to find the most common value across multiple columns - mysql

I was just wondering what MySQL code could I use to find the most common value across a series of columns containing similar values.
SELECT `column`,
COUNT(`column`) AS `value_occurrence`
FROM `my_table`
GROUP BY `column`
ORDER BY `value_occurrence` DESC
LIMIT 1;
I know I can use the above code to the find most common value in a single column but how would I expand this to find the value in 3 columns?
Eg
Column 1: 1, 2, 2, 4
Column 2: 1, 3, 2, 1
Column 3: 1, 2, 2, 2
Result : 2

Use UNION to move all the columns into a single column.
SELECT col, COUNT(*) AS value_occurrence
FROM (
SELECT col1 AS col
FROM my_table
UNION ALL
SELECT col2 AS col
FROM my_table
UNION ALL
SELECT col3 AS col
FROM my_table) AS x
GROUP BY column
ORDER BY value_occurrence DESC
LIMIT 1

All you have to do is replace column in COUNT(column) with an asterisk (*). That is the universal selector for accessing all records of a table. Then in your ORDER BY clause, specify allColumns as the scope of the data you want to order it by.
select allColumns, count(*) as value_occurrence from dataTable
group by allColumns
order by value_occurrence desc, allColumns
LIMIT 1;

Related

How can I query my table to group it by 2 fields in mySQL?

I'm stuck.
I'm trying to query one of my tables to obtain the maximum 'canister_change_date' with grouped pairs 'canister_type' and 'test_cell'.
I've put together a table with some dummy data (below) If you want the create table schema, let me know and I'll put it in the comments.
The final result would either need to have the id's or the whole row with id.
expected result (below) would have id's - 1, 2, 3, 5, 7, 8
6 should be removed as matching pair (test_cell =4, canister_type=Carbon Monoxide) and 7 to be taken as it has the later 'canister_change_date' date.
The expect result would either need to have the id's or id's and rest of fields.
Thanks!
You can use GROUP BY on multiple columns just like that
SELECT COUNT(*) FROM my_table GROUP BY column1, column2
If you want to find row with highest value of some column then you will need HAVING clause and MAX() aggregate function. You can combine them like this
SELECT max_column, column1, column2
GROUP BY column1, column2
HAVING max_column = MAX(max_column)
This example assumes you want to find highest value of max_column for each unique pair of column1 and column2
With NOT EXISTS:
select t.* from tablename
where not exists (
select 1 from tablename
where test_cell = t.test_cell and canister_type = canister_type
and canister_change_date > t.canister_change_date
)
or if your version of MySql is 8.0+ and supports window functions:
select t.* from (
select *,
row_number() over (partition by test_cell, canister_type order by canister_change_date desc) rn
from tablename
) t
where t.rn = 1

Order by FIELD along with subquery?

I want to order the query results by specific values.
Seems like I can use this:
SELECT
column
FROM
table
ORDER BY
IF(
FIELD(
id,
3,1,2
) = 0,
1,
0
) ASC,
FIELD(
id,
3,1,2
)
My problem is that 3,1,2 comes from another table column. Replacing 3,1,2 with (SELECT column from...) is not working properly. Because the SELECT returns the result as "3,1,2" and not as 3,1,2
I can also extract 3,1,2 one by one, but in this case i get error Subquery returns more than 1 row.
What's the solution here ?
Suppose that the statement that returns the values 3, 1, 2 is something like this:
SELECT somecolumn FROM sometable ORDER BY someothercolumn
then you can use GROUP_CONCAT() to create a comma separated string that contains these values:
SELECT GROUP_CONCAT(somecolumn ORDER BY someothercolumn) col FROM sometable
and then use FIND_IN_SET() instead of FIELD():
SELECT t.column
FROM table t
CROSS JOIN (SELECT GROUP_CONCAT(somecolumn col ORDER BY someothercolumn) FROM sometable) s
ORDER BY
SUBSTRING_INDEX(t.id, s.col) = 0,
SUBSTRING_INDEX(t.id, s.col)
I hope that I understood the logic that you want to apply to sort the table with your ORDER BY clause.

List ocurrences in column - SQL

I have a table column that has integers, for example:
2
2
1
2
3
1
3
How do I get the values that occur in this column? In this case the results should be:
1
2
3
I know there's something is Postgre called width_bucket but I couldn't make that work me and I'm not even sure if that is supposed to solve my problem.
Thank you in advance.
Based upon your question, it is a simple select distinct and then an order by
SELECT distinct(Column_Name)
FROM Table_name
ORDER BY Column_Name DESC
Or
SELECT distinct(Column_Name)
FROM Table_name
ORDER BY Column_Name
Depending on the Sort order that you want
You can use distinct keyword or group by clause with the order by:
select distinct col from tbl order by col
select col from tbl group by col order by col

SQL Lower Bound?

I would like to write a sql query that returns all values greater than or equal to x and also the first value that is not greater than x.
For example if we have a table containing values 1, 2, 3, 4, 5 and x is 3, I need to return 2, 3, 4, 5.
The fact that my example includes evenly spaced integers does not help because my actual data is not as cooperative.
Is this even possible or am I better off just getting the entire table and manually figuring out which rows I need?
SELECT <columns> -- you want in the result
FROM tableX
WHERE columnX >=
( SELECT MAX(columnX)
FROM tableX
WHERE columnX < #x -- #x is the parameter, 3 in your example
) ;
union is your best bet. paste together the set of all values greater than x, and the largest value less than x. Something like the following should work:
SELECT n FROM table WHERE n > $x ORDER BY n DESC
UNION SELECT n from table WHERE n < $x ORDER By n DESC LIMIT 0,1;
SELECT * FROM MyTable WHERE MyColumn >= 3
UNION
SELECT * FROM MyTable WHERE MyColumn < 3 ORDER BY MyColumn DESC LIMIT 1

how to find first and last record from mysql table

I have one table I want to find first and last record that satisfy criteria of particular month.
SELECT
(SELECT column FROM table WHERE [condition] ORDER BY column LIMIT 1) as 'first',
(SELECT column FROM table WHERE [condition] ORDER BY column DESC LIMIT 1) as 'last'
This worked for me when I needed to select first and the last date in the event series.
First and last make sense only when you have the output of the query sorted on a field(s).
To get the first record:
select col1 from tab1 order by col1 asc limit 1;
To get the last record:
select col1 from tab1 order by col1 desc limit 1;
How about something like:
select 'first', f1, f2, f3, f4 from tbl
order by f1 asc, f2 asc
limit 1
union all
select 'last', f1, f2, f3, f4 from tbl
order by f1 desc, f2 desc
limit 1
Obviously feel free to add whatever condition you want in a where clause but the basic premise of the order by is to reverse the order in the two select sections.
The limit clause will just get the first row in both cases. That just happens to be the last row of set in the second select due to the fact that you've reversed the ordering.
If there is only one row resulting from your conditions and you don't want it returned twice, use union instead of union all.
select * from table
where id = (select id from tab1 order by col1 asc limit 1) or
id = (select id from tab1 order by col1 desc limit 1);
Try this one: take for example you want to group your table based on group_col and get the first and last value of value_col:
select substring_index(group_concat(value_col), ',',1) as 'first',
substring_index(group_concat(value_col), ',',-1) as 'last'
from table
group by group_col
SELECT * FROM (
SELECT first_name, LENGTH(first_name) FROM Employees
ORDER BY LENGTH(first_name) ASC
FETCH FIRST 1 rows ONLY)
UNION
SELECT * FROM (
SELECT first_name, LENGTH(first_name) FROM Employees
ORDER BY LENGTH(first_name) DESC
FETCH FIRST 1 rows ONLY)
ORDER BY 2 desc;