Convert MariaDb query into MySQL - mysql

I have query in mariaDB, this query is used to (get ancestors of a child (dog) upto Level 5)
WITH RECURSIVE
cte AS (
SELECT *, 0 level, ' ' relation
FROM dogs
WHERE dog_id = 7
UNION ALL
SELECT dogs.*, level + 1, 'father'
FROM dogs
JOIN cte ON cte.father_id = dogs.dog_id
WHERE level < 5
UNION ALL
SELECT dogs.*, level + 1, 'mother'
FROM dogs
JOIN cte ON cte.mother_id = dogs.dog_id
WHERE level < 5
)
SELECT *
FROM cte
ORDER BY level, relation;
I want this query in mysql version: 5.6.45
Here is Table Script:
CREATE TABLE `dogs` (
`dog_id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`father_id` int(11) DEFAULT NULL,
`mother_id` int(11) DEFAULT NULL,
PRIMARY KEY (`dog_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `dogs` VALUES ('0', null, null, null);
INSERT INTO `dogs` VALUES ('1', 'Father', null, null);
INSERT INTO `dogs` VALUES ('2', 'Mother', null, null);
INSERT INTO `dogs` VALUES ('3', 'Father1', null, null);
INSERT INTO `dogs` VALUES ('4', 'Mother2', null, null);
INSERT INTO `dogs` VALUES ('5', 'Son', '1', '2');
INSERT INTO `dogs` VALUES ('6', 'Daughter', '3', '4');
INSERT INTO `dogs` VALUES ('7', 'GrandSon', '5', '6');

Related

How to get rows from table doc_val with minimum "val" from table doc_val for each of the doc_id where criteria = 'L'

You have two tables:
1. docs
2. doc_val
Point of focus is table : doc_val , it has doc_id FK from table docs , field critera which will
be our condition.
Mysql schema:
CREATE TABLE IF NOT EXISTS `docs` (
`id` int(6) unsigned NOT NULL,
`rev` int(3) unsigned NOT NULL,
`content` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `doc_val` (
`id` int(6) unsigned NOT NULL,
`doc_id` int(6) unsigned NOT NULL,
`val` int(3) unsigned NOT NULL,
`type` varchar(2) NOT NULL,
`criteria` varchar(2) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` (`id`, `rev`, `content`) VALUES
('1', '1', 'The earth is flat'),
('2', '1', 'One hundred angels can dance on the head of a pin'),
('3', '1', 'The earth is flat and rests on a bull\'s horn'),
('4', '4', 'The earth is like a ball.');
INSERT INTO `doc_val` (`id`, `doc_id`, `val`, `type`, `criteria`) VALUES
('1', '1', 100, 'D', 'L'),
('2', '1', 101, 'D', 'L'),
('3', '1', 80, 'H', 'L'),
('4', '2', 10, 'H', 'S'),
('5', '2', 90, 'H', 'L'),
('6', '3', 100, 'D', 'L'),
('7', '3', 100, 'D', 'L');
expected output:
DECLARE curIds CURSOR FOR SELECT DISTINCT doc_id FROM doc_val;
DECLARE id INT;
CREATE TEMPORARY TABLE temp(id int, doc_id int, val int, type char(1), criteria char(1));
OPEN curIds;
read_loop: LOOP
FETCH curIds INTO id;
INSERT INTO temp
(Select * from doc_val
where val = (select min(val)
from doc_val
where doc_id = id)) AND criteria = 'L'
END LOOP;
SELECT * FROM temp;
Probably there is a syntax error but i hope you caught the idea.

Is there a tool that can export or import an object from the database

The object I am referring to is about a entity in the data model.
For example, these are the tables in my database:
-- ----------------------------
-- student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_no` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`gender` tinyint(1) NOT NULL,
`age` tinyint(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `student` VALUES ('1', '19001', 'John', '1', '13');
INSERT INTO `student` VALUES ('2', '19002', 'Mary', '2', '12');
INSERT INTO `student` VALUES ('3', '19003', 'Tom', '1', '13');
-- ----------------------------
-- course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `course` VALUES ('1', 'C1');
INSERT INTO `course` VALUES ('2', 'C2');
INSERT INTO `course` VALUES ('3', 'C3');
-- ----------------------------
-- score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`course_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`score` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `score` VALUES ('1', '1', '1', '100');
INSERT INTO `score` VALUES ('2', '1', '2', '96');
INSERT INTO `score` VALUES ('3', '2', '1', '77');
Student entity includes all data associated with it.
I want to export a student entity named Mary, including all of its associated data (courses, scores)
Through the tool, I want to get the output like the following:
1. json like formats:
{
"id": 2,
"student_no": 19002,
"name": "Mary",
"gender": 2,
"age": 12,
"score": [
{
"id": 2,
"course_id": 1,
"student_id": 2,
"score": 96
}
]
}
2. INSERT statments
INSERT INTO `student` (`id`, `student_no`, `name`, `gender`, `age`) VALUES ('2', '19002', 'Mary', '2', '12');
INSERT INTO `score` (`id`, `course_id`, `student_id`, `score`) VALUES ('2', '1', '2', '96');
Any of the above two formats can help achieve my goal.
purpose
The data associated with Mary is the student record and her course score records, so I hope that this tool can help me transfer data from one database to another, or easily delete any associated records about Mary in a database instead of write the SQL statement myself.
Is there such a tool? The tool should be configurable without writing code, to define the tables involved in the entity and the associated fields between them.
Thank you!

Get most recent record from one-to-many relationship

As I say in the title, having this schema:
CREATE TABLE IF NOT EXISTS `services` (
`id` int(6) unsigned NOT NULL,
`description` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `services` (`id`, `description`) VALUES
('1', 'Water flood from kitchen'),
('2', 'Light switch burnt');
CREATE TABLE IF NOT EXISTS `visits` (
`id` int(6) unsigned NOT NULL,
`date` DATETIME NOT NULL,
`description` varchar(200) NOT NULL,
`worker` varchar(200) NOT NULL,
`services_id` int(6) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `visits` (`id`, `date`, `description`, `worker`, `services_id`) VALUES
('1', '2018-12-10 16:00:00', 'Find and stop leak', 'Thomas', '1'),
('2', '2018-12-11 09:00:00', 'Change broken pipe', 'Bob', '1'),
('3', '2018-12-10 19:00:00', 'Change light switch', 'Alfred', '2'),
('4', '2018-12-11 10:00:00', 'Paint wall blackened by shortcircuit', 'Ryan', '2');
I need to get the most recent visit, date-wise, for each service.
In this example, I would get:
'1', '2018-12-10 16:00:00', 'Find and stop leak', 'Thomas', '1'
'3', '2018-12-10 19:00:00', 'Change light switch', 'Alfred', '2'
How would you do it? I'm struggling to get a solution.
Here's the SQLFiddle:
http://sqlfiddle.com/#!9/3ca219
I would suggest a correlated subquery:
select v.*
from visits v
where v.date = (select max(v2.date)
from visits v2
where v2.services_id = v.services_id
);
With an index on visits(services_id, date), this should be as fast or faster than other approaches.

MySQL query: Updating foreign key with unique Id

I need to link two tables 1-to-1, but the values that are to be compared and linked upon, are not unique.
I cannot find a way. As an example, I added a very simple version.
CREATE TABLE `T1` (
`id` int(6) unsigned NOT NULL,
`cmp` int(3) NOT NULL,
`uniqueT2Id` int(3) unsigned,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `T2` (
`id` int(6) unsigned NOT NULL,
`cmp` int(3) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `T1` (`id`, `cmp`, `uniqueT2Id`) VALUES
('1', '1', NULL),
('2', '1', NULL),
('3', '2', NULL),
('4', '3', NULL),
('5', '1', NULL);
INSERT INTO `T2` (`id`, `cmp`) VALUES
('1', '1'),
('2', '1'),
('3', '1'),
('4', '2'),
('5', '3');
UPDATE T1 SET uniqueT2Id=
(SELECT id FROM T2 WHERE T2.cmp=T1.cmp AND
id NOT IN (SELECT * FROM
(SELECT uniqueT2Id FROM T1 WHERE uniqueT2Id IS NOT NULL) X)
ORDER BY id ASC LIMIT 1);
SELECT * FROM T1;
http://sqlfiddle.com/#!9/3bab7c/2/0
The result is
id cmp uniqueT2Id
1 1 1
2 1 1
3 2 4
4 3 5
5 1 1
I want it to be
id rev uniqueT2Id
1 1 1
2 1 2
3 2 4
4 3 5
5 1 3
In the UPDATE I try to pick an Id that is not already used, but this obviously does not work. Does anyone know a way to do this in MySQL, preferrably without PHP?
I found an answer myself, with variables. It is horrible and requires a dummy field in the table, but it works. I am open for improvements.
CREATE TABLE `T1` (
`id` int(6) unsigned NOT NULL,
`cmp` int(3) NOT NULL,
`uniqueT2Id` int(3) NULL,
`dummy` varchar(200) NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `T2` (
`id` int(6) unsigned NOT NULL,
`cmp` int(3) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `T1` (`id`, `cmp`, `uniqueT2Id`) VALUES
('1', '1', NULL),
('2', '1', NULL),
('3', '2', NULL),
('4', '5', NULL),
('5', '3', NULL),
('6', '1', NULL);
INSERT INTO `T2` (`id`, `cmp`) VALUES
('1', '1'),
('2', '1'),
('3', '1'),
('4', '2'),
('5', '3');
SET #taken = '/' ;
UPDATE T1
SET uniqueT2Id= #new:=
(SELECT id FROM T2 WHERE T2.cmp=T1.cmp AND
INSTR(#taken, CONCAT('/',id,'/')) = 0
ORDER BY id ASC LIMIT 1),
dummy=IF(#new IS NOT NULL,#taken:=CONCAT(#taken, #new, "/"),NULL);
http://sqlfiddle.com/#!9/4a61d/1/0

Mysql find users after table pattern

I have the following five tables:
users: id, name
region: id, usersId, region
country: id, usersId, country
status: id, usersId, status
search: id, usersId, region, country, status
The search table includes the given data after what we will search in the other tables.
So, if the search-table has 5 users from 'DE', 'US', 'CH' ... with different or same zipcodes, all users from users, region, country and status should be displayed, where this pattern is true
For example:
I have 10 users in my database and the user with the user.id = 1 stores his data in search-table:
users:
id:8, "John"
search:
id: 8, usersId:1, region: 47798, country: "DE", status: "Boss"
Now i want all other user who comes from 'DE' from the region LIKE "4%" and who works as a "Boss" :-)
This is my database:
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for `country`
-- ----------------------------
DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`country` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `country`
-- ----------------------------
BEGIN;
INSERT INTO `country` VALUES ('1', '1', 'US'), ('2', '2', 'US'), ('3', '3', 'AUT'), ('4', '4', 'DE'), ('5', '5', 'DE'), ('6', '6', 'CH');
COMMIT;
-- ----------------------------
-- Table structure for `region`
-- ----------------------------
DROP TABLE IF EXISTS `region`;
CREATE TABLE `region` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`region` varchar(150) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `region`
-- ----------------------------
BEGIN;
INSERT INTO `region` VALUES ('1', '1', '47798'), ('2', '2', '47798'), ('3', '3', '444'), ('4', '4', '78965'), ('5', '5', '7856'), ('6', '6', '7856');
COMMIT;
-- ----------------------------
-- Table structure for `search`
-- ----------------------------
DROP TABLE IF EXISTS `search`;
CREATE TABLE `search` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country` varchar(100) NOT NULL,
`usersId` int(11) NOT NULL,
`region` varchar(100) NOT NULL,
`status` varchar(150) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `search`
-- ----------------------------
BEGIN;
INSERT INTO `search` VALUES ('1', 'US', '1', '47798', 'Angestellter'), ('2', 'US', '2', '79653', 'Angestellter'), ('3', 'AUT', '3', '444', 'Chef'), ('4', 'DE', '4', '78965', 'Gesellschafter'), ('5', 'DE', '5', '7856', 'Vertrieb'), ('6', 'DE', '6', '47798', 'Angestellter');
COMMIT;
-- ----------------------------
-- Table structure for `status`
-- ----------------------------
DROP TABLE IF EXISTS `status`;
CREATE TABLE `status` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`status` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `status`
-- ----------------------------
BEGIN;
INSERT INTO `status` VALUES ('1', '1', 'Angestellter'), ('2', '2', 'Angestellter'), ('3', '3', 'Chef'), ('4', '4', 'Gesellschafter'), ('5', '5', 'Vertrieb'), ('6', '6', 'Vertrieb');
COMMIT;
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
-- ----------------------------
-- Records of `users`
-- ----------------------------
BEGIN;
INSERT INTO `users` VALUES ('1', 'Heinz'), ('2', 'Karl'), ('3', 'Helmut'), ('4', 'Viktor'), ('5', 'Thomas'), ('6', 'Kurt');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
And this is my Select, what not working correctly, i only geht the search-table entries:
select * from users
inner join region on users.id=region.usersid
inner join country on users.id=country.usersid
inner join status on users.id=status.usersid
where users.id in (select usersId from search where country = 'DE' AND region LIKE '7%');
You can use the following query (modified the select you were using in your question):
select * from users
inner join search
on search.usersid = users.id
where country = 'DE' AND region LIKE '7%'
You can change the where clause as per your requirement.
Also, it is a good practice to maintain consistency in nomenclature of the columns within different tables especially the primary keys/identity columns. For example: In your table definition, Id in users table but usersId in search table.