I have table having few number of columns wherein one column is for Execution number (exe_number) which stores the data in varchar(100).
select*from exedetails;
+------------+------------+------------+-------------+
| exe_number | pass_count | fail_count | error_count |
+------------+------------+------------+-------------+
| 02Aug_E1 | 98 | 9 | 0 |
| 31Jul_E1 | 94 | 8 | 1 |
| 30Jul_E2 | 76 | 9 | 3 |
| 01Aug_E2 | 98 | 7 | 0 |
| 02Aug_E2 | 76 | 8 | 2 |
| 30Jul_E1 | 98 | 12 | 9 |
| 31Jul_E2 | 91 | 6 | 1 |
| 01Aug_E1 | 67 | 14 | 2 |
+------------+------------+------------+-------------+
8 rows in set (0.00 sec)
describe exedetails;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| exe_number | varchar(100) | YES | | NULL | |
| pass_count | int | YES | | NULL | |
| fail_count | int | YES | | NULL | |
| error_count | int | YES | | NULL | |
+-------------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
Here 30/31/01/02 are a date, Aug/Jul is a month and E1/E2 is Execution iteration (This is for my simplicity).
Lets consider present date is
'02 August 2022'
So I want to write a query in such a way that all records starting with
02Aug_
should be at the top of table.
Means It should get arranged according to date so that present day record should be at the top.
Query I wrote for this is not giving desired result:
select exe_number from exedetails order by exe_number desc;
+------------+
| exe_number |
+------------+
| 31Jul_E2 |
| 31Jul_E1 |
| 30Jul_E2 |
| 30Jul_E1 |
| 02Aug_E2 |
| 02Aug_E1 |
| 01Aug_E2 |
| 01Aug_E1 |
+------------+
8 rows in set (0.00 sec)
select exe_number from exedetails order by exe_number asc;
+------------+
| exe_number |
+------------+
| 01Aug_E1 |
| 01Aug_E2 |
| 02Aug_E1 |
| 02Aug_E2 |
| 30Jul_E1 |
| 30Jul_E2 |
| 31Jul_E1 |
| 31Jul_E2 |
+------------+
8 rows in set (0.00 sec)
Expected Result :
+------------+
| exe_number |
+------------+
| 02Aug_E1 |
| 02Aug_E2 |
| 01Aug_E1 |
| 01Aug_E2 |
| 31Jul_E1 |
| 31Jul_E2 |
| 30Jul_E1 |
| 30Jul_E2 |
+------------+
Is there any way in MySQL/PostgreSQL by which I can get my desired solution?
Just convert the "date part" to a proper date value, then you can sort by it:
select *
from exedetails
order by to_date(left(exe_number, 5), 'ddmon') desc,
right(exe_number, 2)
Note that to_date() working with a month name depends on your locale settings and the values in the column.
Online example for Postgres
how can i get the name who's age is max in his grade
Table information:
mysql> select * from stu;
+----+------+------+-------+
| id | name | age | grade |
+----+------+------+-------+
| 1 | a | 11 | 1 |
| 2 | b | 12 | 1 |
| 3 | c | 13 | 1 |
| 4 | d | 11 | 2 |
| 5 | e | 12 | 2 |
| 6 | f | 13 | 2 |
+----+------+------+-------+
6 rows in set (0.00 sec)
mysql> describe stu;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(1) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| grade | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
in this way i can get the max age and grade,but how can i get the name who's age is max in his grade.
mysql> select max(age),grade from stu group by grade;
+----------+-------+
| max(age) | grade |
+----------+-------+
| 13 | 1 |
| 13 | 2 |
+----------+-------+
2 rows in set (0.00 sec)
You could try this:
SELECT A.*
FROM STU A
INNER JOIN (SELECT MAX(AGE) AS MAX_AGE,GRADE FROM STU GROUP BY GRADE ) B ON A.GRADE = B.GRADE AND A.AGE= B.MAX_AGE
Try this:
select max(name), max(age),grade from stu
group by grade
Here is link to : Sqlfiddle
contents of my table
mysql> select * from tb_dts;
+----+------+------+
| Id | key1 | key2 |
+----+------+------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
| 4 | 2 | 1 |
| 5 | 2 | 1 |
| 6 | 2 | 1 |
| 7 | 2 | 1 |
| 8 | 1 | 2 |
| 9 | 1 | 2 |
| 10 | 1 | 2 |
| 11 | 1 | 2 |
| 12 | 1 | 2 |
| 13 | 3 | 1 |
| 14 | 3 | 1 |
| 15 | 3 | 1 |
| 16 | 3 | 1 |
| 17 | 2 | 2 |
| 18 | 2 | 2 |
| 19 | 2 | 2 |
| 20 | 2 | 3 |
| 21 | 2 | 3 |
| 22 | 2 | 3 |
| 23 | 3 | 2 |
| 24 | 3 | 2 |
| 25 | 3 | 2 |
| 26 | 3 | 2 |
+----+------+------+
26 rows in set (0.00 sec)
This is what I tried
mysql> select group_concat(id) from tb_dts group by key1,key2 limit 0,4;
+------------------+
| group_concat(id) |
+------------------+
| 1,2,3 |
| 8,9,10,11,12 |
| 4,5,6,7 |
| 17,18,19 |
+------------------+
4 rows in set (0.00 sec)
mysql> select id from tb_dts group by key1,key2 limit 0,4;
+----+
| id |
+----+
| 1 |
| 8 |
| 4 |
| 17 |
+----+
4 rows in set (0.00 sec)
This is what I expect to get as output for group by key1,key2 limit 0,4; : I want all id in one column, which falls within a limit group by key1 and key2, I don't know how to get it group_concat can't help me on this
for first 4 unique combination of key1,key2 what all id falls is my question that is using group by key1,key2 limit 0,4;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 4 |
| 5 |
| 6 |
| 7 |
| 17 |
| 18 |
| 19 |
+----+
15 rows in set (0.00 sec)
Table Structure
DROP TABLE IF EXISTS `tb_dts`;
CREATE TABLE `tb_dts` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`key1` int(11) DEFAULT '-99',
`key2` int(11) DEFAULT '-99',
PRIMARY KEY (`Id`),
KEY `main` (`key1`,`key2`)
) ENGINE=MyISAM AUTO_INCREMENT=27 DEFAULT CHARSET=latin1;
LOCK TABLES `tb_dts` WRITE;
INSERT INTO `tb_dts` VALUES (1,1,1),(2,1,1),(3,1,1),(4,2,1),(5,2,1),(6,2,1),(7,2,1),(8,1,2),(9,1,2),(10,1,2),(11,1,2),(12,1,2),(13,3,1),(14,3,1),(15,3,1),(16,3,1),(17,2,2),(18,2,2),(19,2,2),(20,2,3),(21,2,3),(22,2,3),(23,3,2),(24,3,2),(25,3,2),(26,3,2);
UNLOCK TABLES;
Use the Separator as below
select group_concat(id SEPARATOR '\n') from tb_dts group by key1,key2
If order doesn't matter then try :
See Output here : SQL Fiddle
select id
from tb_dts
where (key1,key2) in (
select key1,key2
from (
select distinct key1,key2 from tb_dts limit 0,4
) as sub
);
There is a way to solve question.
First you have to create a Table like
CREATE TABLE `Tmp` (
`Id` int(11)
);
And then, after you run the code
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 0,1;
--#TmpStr = "1,2,3"
Write a funtion to Split #TmpStr by "," and Insert into Tmp separately.
And keep doing same thing for
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 1,1;
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 2,1;
select #TmpStr = group_concat(id) from tb_dts group by key1,key2 limit 3,1;
it will show the result like you want.
If I have multiple objects and anyone can potentially map to multiple other ones.
A -> B, C, D, E
B -> A, E, F, C
C -> B
etc.
How would I store these entities in MySql and use JPA + Hibernate to manage them. For example, If I search "A", it will return "B,C,D,E", and if I search "C", it will return "B", etc.
Edited:
Follow suggestion, I did the following:
[test]> describe relation;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| id_start | int(11) | YES | | NULL | |
| id_end | int(11) | YES | MUL | NULL | |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
MariaDB [test]> describe entity;
+-------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(5) | YES | | NULL | |
+-------+------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
MariaDB [test]> select * from entity;
+----+------+
| id | name |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
| 6 | F |
+----+------+
6 rows in set (0.00 sec)
MariaDB [test]> select * from relation;
+----+----------+--------+
| id | id_start | id_end |
+----+----------+--------+
| 1 | 3 | 1 |
| 2 | 2 | 1 |
| 3 | 4 | 1 |
| 4 | 5 | 1 |
| 5 | 1 | 2 |
| 6 | 5 | 2 |
| 7 | 6 | 2 |
| 8 | 3 | 2 |
| 9 | 2 | 3 |
+----+----------+--------+
9 rows in set (0.00 sec)
[test]> select E.name, R.id_start from relation R join entity E on E.id=R.id_end where E.name="A";
+------+----------+
| name | id_start |
+------+----------+
| A | 3 |
| A | 2 |
| A | 4 |
| A | 5 |
+------+----------+
Question:
This query returns the related Ids of 'A', which is right, but not actually B, C, D, E. How to get the actual related names from entity table? Is it a database design or SQL statement mistake?
So, here is the structure:
mysql> describe tier;
+---------------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+----------------+------+-----+---------+----------------+
| ID | int(10) | NO | PRI | NULL | auto_increment |
| UP_TO | decimal(21,10) | YES | | NULL | |
+---------------------+----------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
Then the datas:
mysql> select id, up_to from tier;
+----+-----------------+
| id | up_to |
+----+-----------------+
| 1 | 1000.0000000000 |
| 2 | 2000.0000000000 |
| 3 | 3000.0000000000 |
| 4 | 500.0000000000 |
| 5 | 1000.0000000000 |
| 6 | 1500.0000000000 |
| 7 | 100.0000000000 |
| 8 | 200.0000000000 |
| 9 | 1000.0000000000 |
| 10 | 2000.0000000000 |
| 11 | 100.0000000000 |
| 12 | 200.0000000000 |
+----+-----------------+
12 rows in set (0.00 sec)
Then there's a little transformation:
mysql> SELECT id, TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM CAST(up_to AS CH
AR) )) as converted from tier;
+----+-----------+
| id | converted |
+----+-----------+
| 1 | 1000 |
| 2 | 2000 |
| 3 | 3000 |
| 4 | 500 |
| 5 | 1000 |
| 6 | 1500 |
| 7 | 100 |
| 8 | 200 |
| 9 | 1000 |
| 10 | 2000 |
| 11 | 100 |
| 12 | 200 |
+----+-----------+
12 rows in set (0.00 sec)
Fine.
Let's put that in a stored function to be handy!
DELIMITER //
CREATE FUNCTION strip_trailing_zero(I_DEC DECIMAL(10,7)) RETURNS VARCHAR(20) DETERMINISTIC
BEGIN
DECLARE strBuff VARCHAR(20);
DECLARE cnt NUMERIC(2);
DECLARE tString VARCHAR(20);
SELECT CAST(I_DEC AS CHAR) INTO tString;
SELECT LOCATE('.',tString) INTO cnt;
IF cnt > 0 THEN
SELECT TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM tString)) INTO strBuff;
ELSE
SET strBuff = tString;
END IF;
RETURN strBuff;
END//
DELIMITER ;
Cool.
GRANT EXECUTE ON FUNCTION mysql.strip_trailing_zero TO 'whatever'#'localhost';
At last, trying out my new toy now... :
mysql> select id, mysql.strip_trailing_zero(`up_to`) as converted_2 from tier;
+----+-------------+
| id | converted_2 |
+----+-------------+
| 1 | 999.9999999 |
| 2 | 999.9999999 |
| 3 | 999.9999999 |
| 4 | 500 |
| 5 | 999.9999999 |
| 6 | 999.9999999 |
| 7 | 100 |
| 8 | 200 |
| 9 | 999.9999999 |
| 10 | 999.9999999 |
| 11 | 100 |
| 12 | 200 |
+----+-------------+
12 rows in set, 7 warnings (0.02 sec)
Well, then, f*ck you too mysql!
No seriously, that's a silly joke. I'm convinced I did something wrong and there's a floating point conversion in the middle but I just can't figure it out!
Help welcome!
Thanks.
S.
edit: result after changing the input parameter type to DECIMAL(21,10):
mysql> select id, mysql.strip_trailing_zero(`up_to`) as converted_2 from tier;
+----+-------------+
| id | converted_2 |
+----+-------------+
| 1 | 1000 |
| 2 | 2000 |
| 3 | 3000 |
| 4 | 500 |
| 5 | 1000 |
| 6 | 1500 |
| 7 | 100 |
| 8 | 200 |
| 9 | 1000 |
| 10 | 2000 |
| 11 | 100 |
| 12 | 200 |
+----+-------------+
12 rows in set (0.02 sec)
Problem solved... Great! thank you!
Your UP_TO field in your table is defined as decimal(21,10), but your function takes in a decimal(10,7). I imagine that is stripping your value.
Try changing your function to accept decimal(21,10) instead.