Grouping by multiple columns with equal priority in MySQL - mysql

I have a table of data, and I want to be able to output all the data that does not repeat the contents of two columns, an illustration:
Example table:
Column1 | Column2 | Column3
1 XX pop
2 YY yif
3 ZZ pop
4 PP pop
5 XX pop
6 YY yif
7 PP Hor
8 MM tre
9 PP pop
10 XX pop
11 MM pop
What I want to do here is output all rows where the values for both Columns 2 and 3 are not repeated, so you will see that Column1 == 1 and Column1 == 5 have the same values in both Column2 and Column3, so they only need to output where Column1 == 1 and not =5 (or =10).
I would like to set the query to output all rows, except where Column1 == 5,6,9,10 because these have both Column2 and Column3 repetition.
Intended output of query: (note: all three columns are required)
Column1 | Column2 | Column3
1 XX pop
2 YY yif
3 ZZ pop
4 PP pop
7 PP Hor
8 MM tre
11 MM pop
I have tried looking into Group By but this only appears to group by one column, or at least groups them from left to right so GROUP BY (Column2, Column3) would GROUP BY all values in Column2 and then values in Column3 rather than treat both columns equally.
I found one possible solution which was to concat the columns beforehand, such as
GROUP BY CONCAT(Column2, '_', Column3)
From Is it possible to GROUP BY multiple columns using MySQL? but this has been vaguely criticised (at least, as an answer to that question), but seems the closest code I've seen to do what I want to do.
So, how should I structure my GROUP BY clause to reach this outcome?
Is the GROUP BY CONCAT I have found a good way of approaching this?

GROUP BY on multiple columns is possible. Depending on the result you want, you have to apply extra GROUP functions to the rest of your data. In your case it looks like you want the first column1 index, and unique combinations of (column2,column3)
The following query should do the trick:
SELECT MIN(column1) AS column1,column2,column3
FROM table1
GROUP BY column2,column3
ORDER BY MIN(column1) ASC;

If you don't care about Column1 at all, you don't even need GROUP BY. Just use DISTINCT
SELECT DISTINCT Column2, Column3
FROM the_table
ORDER BY however_you_want
;
Otherwise, Norbert's answer is probably more fitting.

Related

SQL query statement Self Join?

new to SQL.
I have the following set of data
A X Y Z
1 Wind 1 1
2 Wind 2 1
3 Hail 1 1
4 Flood 1 1
4 Rain 1 1
4 Fire 1 1
I would like to select all distinct 'A' fields where for all rows that contain A have flood and rain.
So in this example, the query would return only the number 4 since for the set of all rows that contain A = 4 we have Flood and Rain.
I need the values of A where for a given value 'a' in A, there exists rows with 'a' that must contain all of the following fields provided (in the example Flood and Rain).
Please let me know if you need further clarification.
I need the values of A where for a given value 'a' in A, there exists rows with 'a' that must contain all of the following fields provided (in the example Flood and Rain).
You can use aggregation, and filter with a having clause:
select a
from mytable t
where x in ('Flood', 'Rain') -- either one or the other
having count(*) = 2 -- both match
If tuples (a, x) tuples are not unique, then you want having count(distinct x) = 2 instead.
You Shooud use count(distinct X) group by A and having
count(distinct...) avoid situation where you have two time the same value for X
select A
from my_table
WHERE x in ('Flood', 'Rain')
group A
having count(distinct X) = 2

How to get distinct records but on base on first 2 digits only in MySQL

I want to get distinct records (only one field) from a MySQL table, and that field contain only digits.
Example:
00010000
01111100
01112000
01118000
02301201
But distinct records is considered on base on first 2 digits. So in the case above, I need to get back only 3 records:
00010000
01112000
02301201
More over, I would like to trim the rest of the digits, so the actual end result should be:
00
01
02
So distinct and group by will not cut here. Any idea?
Assuming you wanted the least value from among duplicates, you could try:
SELECT t1.col
FROM yourTable t1
INNER JOIN
(
SELECT LEFT(col, 2) AS prefix, MIN(col) AS min_col
FROM yourTable
GROUP BY LEFT(col, 2)
) t2
ON LEFT(t1.col, 2) = t2.prefix AND
t1.col = t2.min_col;
Note: Numbers in MySQL don't start with zeroes, so your requirement (and this answer) only make sense if your column is text.
DISTINCT will work fine with LEFT to give the results you want:
SELECT DISTINCT(LEFT(value, 2)) AS value
FROM data
ORDER BY value
Output
00
01
02
Demo on dbfiddle
If you only want the trimmed value, try this:
SELECT SUBSTRING(yourColumn,1,2) as trimmedval
FROM Table
GROUP BY SUBSTRING(yourColumn,1,2)

SSRS-Problem in Comparing rows under a group and show it Matched or Unmatched

I have data looks like below, and am grouping at Column1. I need to compare column2 with in Group and highlight if the values for column2 is same or different in Column3-
Column1 Column2 Column3
123 111
123 111
1234 2222
1234 2222
1234 3333
I am using expression in Column3 as below. As you can at last "Column1" I have mentioned it considering it will group and then compare.
=IIF(Fields!Column2.Value = Previous(Fields!Column2.Value), "Same", IIF (Fields!Column2.Value <> Previous(Fields!Column2.Value), "Different")), "Column1"
My expectation is as below, i.e. column3 should populate if all value of Column2 is same under a group (column1 grouping) then Column3 should populare same else different for all rows under a group
Column1 Column2 Column3
123 111 Same
123 111 Same
1234 2222 Different
1234 2222 Different
1234 3333 Different
You can use CountDistinct for this.
If we assume your Column1 'RowGroup' is called grpCol1 then the expression in column 3 would look something liek this.
= IIF(CountDistinct(Fields!Column2.Value,"grpCol1") >1 , "Different", "Same")
Basically this says.. Count how many different Column2 values there are within the the row group grpCol1
So for the first two rows in your example it would return 1 as there is only 1 distinct value, for the next three rows, it would return 2 as there are 2 distinct values.
Note: grpCol1 or whatever your row group is called must be within qoutes and is case sensitive.
A simpler way would be:
=IIF(Fields!Column2.Value = Fields!Column1.Value, "Same", "Different")

MySQL query (condition)

I want to achieve one thing though I'm not sure if it's possible.
So let's say I have a table with few columns, but only two of them are of interest to me right now. Example of table:
Column 1 | Column 2
blabla | blablahhhhh
wor154 | blablahhhhh
word123 | word12435564
something | some4565
What I want to achieve, is to select all fields where first 5 or more symbols of value of Column 2 don't match with first 5 or more symbols of value of Column 1. So I don't want to select rows where 5 or more symbols of value of Column 1 match 5 or more symbols of value of Column 2. In example, query should return only 2nd and 4th rows
So, is it possible and if it's, how it can be achieved. Thank you.
I'd go with a SUBSTRING():
SELECT col1 FROM table WHERE SUBSTRING(col1, 1, 5) <> SUBSTRING(col2, 1, 5);
You can use something similar to this:
select *
from table1
where substring(column1, 1, 5) != substring(column2, 1, 5)
See SQL Fiddle with Demo

Simple MySQL Query - Change table format around

I'm fairly sure this is a fairly easy answer but the answer is completely slipping my mind.
I have a database table that is currently formatted like:
event_id | elem_id | value
1 1 Value 1
1 2 Value 2
2 1 Value 3
2 2 Value 4
Both event_id and elem_id are undetermined numbers and have infinite possibilities.
How would I query it for example based on event_id 1 to get the data to be formatted as such:
event_id | 1 | 2
1 Value 1 Value 2
Knowing that elem_id is a number >= n so potentially there could be 50 elem_id yet I still need the data in that format.
Like I said I can't for the life of me figure out the query to assemble it that way. Any help would be GREATLY appreciated.
Try following:
SELECT
`event_id`,
(SELECT t2.`value` FROM table t2 WHERE t2.`event_id` = t1.`event_id` AND t2.`elem_id` = 1),
(SELECT t3.`value` FROM table t3 WHERE t3.`event_id` = t1.`event_id` AND t3.`elem_id` = 2)
FROM `table` t1 GROUP BY `event_id`;
Also you can use different way, and get elem_ids and values in comma-separated format in two cells
SELECT `event_id`, GROUP_CONCAT(`elem_id`), GROUP_CONCAT(`value`) FROM `table` GROUP BY `event_id`;
and you can change separator with following syntax: GROUP_CONCAT(field SEPARATOR '::')