Minimum values from the table - mysql
I need the minimum value from 3 coloumn and corresponding name for the min value,
like this..
Name val1 val2 val3
a 12 5 4
b 10 9 1
c 7 11 5
d 13 8 2
output:
Name MIN
b 1
I wrote query to find minimum value :
select MIN(less)
from (
select case
when val1<=val2 and val1<=val3 then val1
when val2<=val1 and val2<=val3 then val2
when val3<=val1 and val3<=val2 then val3 end as less from table) as low
I used alises,i want to display the corresponding name from the table...plz tell me the query...
You can do it using the UNION operator to convert the 3 column table into a single table with 1 column.
SELECT TOP 1 Name, Val AS Min
FROM (
SELECT Name, val1 AS Val
FROM table
UNION
SELECT Name, val2 AS Val
FROM table
UNION
SELECT Name, val3 AS Val
FROM table
) AS sub_query
ORDER BY Val ASC
This solution has the added advantage that it is easier to maintain if the number of columns increases.
Most Concise
SELECT top 1 Name,col,val
FROM T
UNPIVOT ( val for col in (val1,val2,val3)) unpvt
ORDER BY val
Most Efficient (assuming these columns are indexed)
;WITH cte(Name, col, val) AS
(
SELECT TOP 1 Name, 'val1', val1
FROM T
ORDER BY val1
UNION ALL
SELECT TOP 1 Name, 'val2', val2
FROM T
ORDER BY val2
UNION ALL
SELECT TOP 1 Name, 'val3', val3
FROM T
ORDER BY val3
)
SELECT TOP 1 Name, col, val
FROM cte
ORDER BY val
Related
how to combine multiple rows into one row?
My table: id val -------- a 1 a 2 a 3 b 7 b 8 b 9 b 10 What i want to get is: id val1 val2 val3 val4 -------------------------- a 1 2 3 null b 7 8 9 10 Is there any simple way for this?
If you are using MySQL 8+, then ROW_NUMBER combined with pivoting logic provides one way: WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY val) rn FROM yourTable ) SELECT id, MAX(CASE WHEN rn = 1 THEN val END) AS val1, MAX(CASE WHEN rn = 2 THEN val END) AS val2, MAX(CASE WHEN rn = 3 THEN val END) AS val3, MAX(CASE WHEN rn = 4 THEN val END) AS val4 FROM cte GROUP BY id;
Not quite the same output, but worth considering: SELECT id, GROUP_CONCAT(val) FROM tbl GROUP BY id;
Match duplicate value from 2 colums and 1 unique value from 1 column mysql
I have this table, here is my db Fiddle CREATE TABLE table1 ( `ID` VARCHAR(100), `Val` VARCHAR(100), `Val2` VARCHAR(100), `Val3` VARCHAR(100) ); INSERT INTO table1 (`ID`, `Val`, `Val2`, `Val3`) VALUES ('1','100','200','90'), ('2','100','200','10'), ('3','100','200','20'), ('4','20','100','55'), ('5','20','100','10'), ('6','112','100','20'), ('7','112','100','20'), ('8','90','200','90'), ('9','30','90','180'), ('10','30','90','29'); I want the result with this condition Val had to be duplicate AND Val2 had to be duplicate AND After i got the duplicate value, now i need to check the val3 from the duplicate value if the value of val3 had unique value from the previous aggregate i tried with this query SELECT t1.* FROM table1 t1 WHERE EXISTS ( SELECT 1 FROM table1 WHERE ID <> t1.ID AND Val = t1.Val AND Val2 = t1.Val2 ) AND NOT EXISTS ( SELECT 1 FROM table1 WHERE Val = t1.Val AND Val2 = t1.Val2 AND Val3 IN ( SELECT Val3 FROM table1 GROUP BY Val3 HAVING count( * ) > 1 ) ) I expect the result would be like this ID Val Val2 Val3 1 100 200 90 2 100 200 10 3 100 200 20 4 20 100 55 5 20 100 10 9 30 90 180 10 30 90 29 BUt i got the result like this ID Val Val2 Val3 9 30 90 180 10 30 90 29 Sample 2 INSERT INTO table1 (`ID`, `Val`, `Val2`, `Val3`) VALUES ('1','100','200','90'), ('2','100','200','10'), ('3','100','200','20'), ('19','100','200','20'), ('4','20','100','55'), ('5','20','100','10'), ('6','112','100','20'), ('7','112','100','20'), ('8','90','200','90'), ('9','30','90','180'), ('10','30','90','29'); Expected result 2 ID Val Val2 Val3 1 100 200 90 2 100 200 10 4 20 100 55 5 20 100 10 9 30 90 180 10 30 90 29 dbfiddle 2 Sample 3 INSERT INTO table1 (`ID`, `Val`, `Val2`, `Val3`) VALUES ('1','100','200','aa'), ('2','100','200','aa'), ('3','100','200','aa'), ('19','100','200','ab'), ('4','20','100','SD2'), ('5','20','100','SD1'), ('6','112','100','aa'), ('7','112','100','ab'), ('8','90','200','aa'), ('9','30','90','SF2'), ('10','30','90','SF1'); Expected result 3 ID Val Val2 Val3 4 20 100 SD2 5 20 100 SD1 6 112 100 aa 7 112 100 ab 9 30 90 SF2 10 30 90 SF1 Some people might be confused with sample 3, so here is a notes for sample 3 : For this case, ID 19 in sample 3 had same value with column val and val2 for id 1, 2, 3 ( 100 and 200), but these id (1, 2, 3) had same aa value in val3, so id 1,2,3 must be excluded, because these id did not match with last condition (val, val2, val3) is unique. ID 19 is fine but val dan val2 column that had duplicate value which is id 1,2,and 3 had already excluded, it makes id 19 had no duplicate value for both column val and val2. if there was another data like '200','100','200','ae' in sample 3, the id 19 will included in result because it has duplicate value beside id 1,2,and 3. for sample 3 ID 19 will be included if the data in table1 were like this Sample 3 ( different case ) INSERT INTO table1 (`ID`, `Val`, `Val2`, `Val3`) VALUES ('1','100','200','aa'), ('2','100','200','aa'), ('3','100','200','aa'), ('19','100','200','ab'), ('200','100','200','ae'), ('4','20','100','SD2'), ('5','20','100','SD1'), ('6','112','100','aa'), ('7','112','100','ab'), ('8','90','200','aa'), ('9','30','90','SF2'), ('10','30','90','SF1'); The expected result will be like this ID Val Val2 Val3 4 20 100 SD2 5 20 100 SD1 19 100 200 ab 200 100 200 ae 6 112 100 aa 7 112 100 ab 9 30 90 SF2 10 30 90 SF1
Join the table to the queries that apply your conditions: select distinct t.* from ( select val, val2 from table1 group by val, val2 having count(*) > 1 ) t1 inner join ( select val, val2, val3 from table1 group by val, val2, val3 having count(*) = 1 ) t2 on t2.val = t1.val and t2.val2 = t1.val2 inner join ( select val, val2, val3 from table1 group by val, val2, val3 having count(*) = 1 ) t3 on t3.val = t1.val and t3.val2 = t1.val2 and t3.val3 <> t2.val3 inner join table1 t on t2.val = t.val and t2.val2 = t.val2 and t.val3 in (t2.val3, t3.val3) See demo1, demo2, demo3, demo4.
As I understand your question, you want rows whose (val, val2) tuple is not unique, and whose (val, val2, val3) is unique. Here is one way to express this by filtering the dataset with correlated subquery: select t1.* from table1 t1 where ( select count(*) from table1 t2 where t2.val = t1.val and t2.val2 = t1.val2 ) > 1 and ( select count(*) from table1 t2 where t2.val = t1.val and t2.val2 = t1.val2 and t2.val3 = t1.val3 ) = 1 order by id For performance, consider an index on (val, val1, val2) (the ordering of columns in the index matters here). If you are lucky enough to be running MySQL 8.0, this can be phrased more simply and more efficiently using window functions: select id, val, val2, val3 from ( select t1.*, count(*) over(partition by val, val2) cnt_1, count(*) over(partition by val, val2, val3) cnt_2 from table1 t1 ) t where cnt_1 > 1 and cnt_2 = 1
As #GMB told in rather simplified manner in his answer, you want rows whose (val, val2) tuple is not unique, and whose (val, val2, val3) is unique. Following query should accomplish that very easily: select t.* from table1 t inner join ( select t1.val, t1.val2 from table1 t1 inner join (select val,val2,val3 from table1 group by val,val2,val3 having count(val3) = 1 ) t2 on t1.val = t2.val and t1.val2 = t2.val2 and t1.val3 = t2.val3 group by t1.val, t1.val2 having count(distinct t1.id) > 1 ) tmp on tmp.val = t.val and tmp.val2 = t.val2 inner join (select val,val2,val3 from table1 group by val,val2,val3 having count(val3) = 1 ) t3 on t.val = t3.val and t.val2 = t3.val2 and t.val3 = t3.val3 Please find the fiddle link for Sample1, Sample2, Sample3 and Sample4.
SQL Select rows where col1 or col2 equals variable
So I want to select rows from table where col1 or col2 equals to variable, but if there is already row selected where col1 equals to variable (variable X) and col2 is anything else (variable Y) then it won't select another row where col2 equals to variable X and col1 equals to that variable Y. Everything ordered by column TIME descending. Let's say this is my table: COL1 COL2 TIME COL4 1 2 0 A 1 2 1 B 2 1 2 C 1 3 3 D 3 1 4 E 4 2 5 F 3 4 6 G 1 2 7 H 4 1 8 I And let's say that variable X equals to 1, then I want to have these rows: COL1 COL2 TIME COL4 4 1 8 I 1 2 7 H 3 1 4 E So it won't show me this row COL1 COL2 TIME COL4 2 1 2 C because there is already a combination where col1/col2 is 2/1 or 1/2. Sorry if I explained it in a bad way, but I can't think of better explanation. Thank you guys.
Making a couple of key assumptions... SELECT a.* FROM my_table a JOIN ( SELECT MAX(time) time FROM my_table WHERE 1 IN (COL1,COL2) GROUP BY LEAST(col1,col2) , GREATEST(col1,col2) ) b ON b.time = a.time;
EDIT: I posted this answer when it was thought that OP's database was SQL Server. But as it turns out, the database is MySQL. I think this query should do it: select t.col1, t.col2, t.time, t.col4 from (select t.*, row_number() over ( partition by case when col1 < col2 then col1 else col2 end, case when col1 < col2 then col2 else col1 end order by time desc) as rn from tbl t where t.col1 = x or t.col2 = x) t where t.rn = 1 order by t.time desc The key part is defining the row_number partition by clause in such a way that (1, 2) is considered equivalent to (2, 1), which is what the case statements do. Once the partitioning works correctly, you just need to keep the first row of every "partition" (where t.rn = 1) to exclude duplicate rows.
How to group repeated row values in a column
t_no name value 1 a 45 1 b 23 1 c 5 1 a 12 1 b 99 1 c 6 I need to show my above table as no name value1 value2 1 a 45 12 1 b 23 99 1 c 5 6
You can't create dynamic columns in mysql alone, either in scripting language, or you can use group_concat to have them in one column: SELECT to_no, name, GROUP_CONCAT(value) FROM table GROUP BY to_no, name result: no name value 1 a 45,12 1 b 23,99 1 c 5,6
MySQL does not have a pivot function, but you can use an aggregate function with a CASE expression. Since you have multiple values for each t_no and name, then you could use user defined variables to assign a row number to each group of values: select t_no, name, max(case when rn=1 then value end) value1, max(case when rn=2 then value end) value2 from ( select t_no, name, value, #rn:=case when #prev=t_no and #c=name then #rn else 0 end +1 rn, #prev:=t_no, #c:=name from yourtable cross join (select #rn:=0, #prev:=0, #c:=null) c order by t_no, name ) d group by t_no, name order by t_no, name; See SQL Fiddle with Demo
How to compare and change values in MYSQL
My table looks like: [Number] [Value1] 1234567 8 1234567C 7 9876543 1 9876543C 2 5555555 3 5555555C 3 I want to search the entries for same values in the first column (except the "C" in the end of the number) and set the higher value in the second column to the lower one. There are always only two same values (one with "C") and some pairs have same values in the second column and some have different. The result of the query should be: Number Value1 1234567 7 1234567C 7 9876543 1 9876543C 1 5555555 3 5555555C 3
The following is not an ideal solution but should do what you want: update yourTable set value1 = ( select min(value1) from ( select * from yourTable ) as x where yourTable.number = x.number + 'C'); I have tested it with this in mysql workbench: create table yourTable(number varchar (10),value1 int); insert into yourTable Values('1234567',8); insert into yourTable Values('1234567C',7); insert into yourTable Values('9876543',1); insert into yourTable Values('9876543C',2); insert into yourTable Values('5555555',3); insert into yourTable Values('5555555C',3); insert into yourTable Values('55555556',10); insert into yourTable Values('55555556C',2); Then select * from yourTable;will return: 1234567 8 1234567C 7 9876543 1 9876543C 2 5555555 3 5555555C 3 55555556 10 55555556C 2 After the update select * from yourTable; will return: 1234567 7 1234567C 7 9876543 1 9876543C 1 5555555 3 5555555C 3 55555556 2 55555556C 2 Hope that is what you wanted :)
Actually, you don't need any checking, since there are only 2 values (and thus the query is even simpler): UPDATE table SET Value1 = ( SELECT MAX(Value1) FROM table t WHERE table.Number = t.Number OR table.Number = t.Number + 'C' ) WHERE RIGHT(Number, 1) != 'C'