Converting SQL file To CSV - mysql

I have dumped a sql table for cities, regions & countries.
I have the .sql files in my local machine. I need to convert them to CSV format.
So I have a 2 part question.
1): What is the best way to do this? Is any tools I can use? (I have a Mac)
2):
I found this site. So I tried with this code:
CREATE TABLE IF NOT EXISTS `countries` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`code` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=231 DEFAULT CHARSET=latin1;
-- Dumping data for table dddblog.countries: ~218 rows (approximately)
/*!40000 ALTER TABLE `countries` DISABLE KEYS */;
INSERT INTO `countries` (`id`, `name`, `code`) VALUES
(1, 'Andorra', 'ad'),
(2, 'United Arab Emirates', 'ae'),
(3, 'Afghanistan', 'af'),
(4, 'Antigua and Barbuda', 'ag'),
(5, 'Anguilla', 'ai'),
(6, 'Albania', 'al'),
(7, 'Armenia', 'am'),
(8, 'Netherlands Antilles', 'an'),
(9, 'Angola', 'ao'),
// Other countries
/*!40000 ALTER TABLE `countries` ENABLE KEYS */;
And when I click on Convert, I get error: Missing SELECT STATEMENT.
Im not familiar with SQL and any help is appreciated!

The message Missing SELECT STATEMENT says it all: You have to add a SELECT statement.
Try it with this code - worked for me:
CREATE TABLE IF NOT EXISTS `countries` (
`id` smallint(5) NOT NULL ,
`name` varchar(255) NOT NULL,
`code` varchar(10) NOT NULL
);
INSERT INTO `countries` (`id`, `name`, `code`) VALUES
(1, 'Andorra', 'ad'),
(2, 'United Arab Emirates', 'ae'),
(3, 'Afghanistan', 'af'),
(4, 'Antigua and Barbuda', 'ag'),
(5, 'Anguilla', 'ai'),
(6, 'Albania', 'al'),
(7, 'Armenia', 'am'),
(8, 'Netherlands Antilles', 'an'),
(9, 'Angola', 'ao')
;
SELECT `id`, `name`, `code` FROM `countries`

Related

How to implement IF condition in two relational tables?

I have two relational tables, and I would like to filter data using IF condition. The problem is that using LEFT JOIN I got records that cannot be grouped.
The tables that I have are:
calendar
bookers
The first table consists of lessons that can be booked by more people, and the second table contains data who booked each lesson. The IF condition that I would like to implement is: return '2' if lesson is booked by specific user, return '1' if lesson is booked, but by another user, and return '0' if lesson is not booked.
What I would like to get according to above tables is given in the figure below.
Expected result
But, when I use LEFT JOIN to link those tables, I got record for every user that booked specific lesson.
SELECT calendar.id, calendarId, lessonType, description,
CASE
WHEN bookedBy then IF(bookedBy = 8, '2', '1')
ELSE '0'
END AS bb,
(select count(bookedBy) from bookers where calendar.id = bookers.lessonId) as nOfBookers
FROM calendar
LEFT JOIN bookers ON calendar.id = bookers.lessonId
WHERE `calendarId`= 180
Without the LEFT JOIN (fiddle), counts are shown properly, but I cannot include IF condition, because the table bookers is not defined.
I would appreciate any help. Thank you very much in advance.
Here is the Fiddle.
CREATE TABLE `calendar` (
`id` int(11) NOT NULL,
`calendarId` varchar(50) NOT NULL,
`lessonType` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `calendar`
(`id`, `calendarId`, `lessonType`, `description`)
VALUES
(1, '180', 'A', ''),
(2, '180', 'A', ''),
(3, '180', 'A', ''),
(4, '180', 'B', ''),
(5, '180', 'B', ''),
(6, '180', 'B', ''),
(7, '180', 'B', ''),
(8, '180', 'B', ''),
(9, '180', 'B', '');
CREATE TABLE `bookers` (
`id` int(11) NOT NULL,
`lessonId` int(11) DEFAULT NULL,
`bookedBy` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `bookers`
--
INSERT INTO `bookers` (`id`, `lessonId`, `bookedBy`) VALUES
(4, 1, 8),
(5, 2, 8),
(6, 2, 28),
(7, 2, 17),
(8, 3, 11);
--
-- Indexes for dumped tables
--
ALTER TABLE `calendar`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `id` (`id`);
--
-- Indexes for table `bookers`
--
ALTER TABLE `bookers`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `bookers`
--
ALTER TABLE `bookers`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;
COMMIT;
select version();
Try this:
SELECT id, calendarid, lessontype, description,
CASE WHEN FIND_IN_SET(8,vbb)>0 THEN 2
WHEN vbb IS NOT NULL THEN 1
ELSE 0 END AS bb,
nOfBookers
FROM
(SELECT c.id, calendarId, lessonType, GROUP_CONCAT(bookedby) AS vbb, description,
(SELECT COUNT(bookedby) FROM bookers WHERE c.id = bookers.lessonId) AS nOfBookers
FROM calendar c
LEFT JOIN bookers b ON c.id = b.lessonId
WHERE `calendarId`= 180
GROUP BY c.id, calendarId, lessonType, description) A;
In addition to your original LEFT JOIN attempt, I've added GROUP_CONCAT(bookedby) AS vbb which will return a comma separated bookedby value; which is 17,28,8. After that, I make the query as a sub-query and do CASE expression with FIND_IN_SET function on vbb to look for specific bookedby.
Here's an update fiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=0933e9fc3cb7445311c34c6705d11637

Get only first result in subquery for each row order by custom column

my brain can't resolve a simple (i think) SQL problem and i need your help. I searched a lot of Stackoverflow but can't find the right answer for my case.
What i have :
table : expense_budgets
id
per_member
maximum
from_date
organization_id
organization_type_id
created_at
updated_at
CREATE TABLE IF NOT EXISTS `expense_budgets` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`per_member` double NOT NULL,
`maximum` double NOT NULL,
`from_date` date DEFAULT NULL,
`organization_id` bigint(20) unsigned DEFAULT NULL,
`organization_type_id` bigint(20) unsigned NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (1, 10, 10000, NULL, NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (2, 5, 5000, NULL, NULL, 3, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (3, 10, 40, NULL, NULL, 4, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (4, 5, 5000, NULL, NULL, 5, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (6, 15, 15000, '2020-09-25', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (7, 15, 15000, '2020-09-29', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (8, 15, 15000, '2020-09-26', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (9, 15, 15000, '2020-09-27', NULL, 2, '2020-09-14 16:43:52', NULL);
What i want : I have to get the closest expense_budget record for each of my organization types for a given date. So i apply a weight custom column to order them. If i have only one record with a null from_date that means that is the default value, if i have a date i want the closest lower from_date from now.
SELECT id, organization_type_id, case when from_date IS null then 1 when CURDATE() >= from_date THEN 3 ELSE 2 END AS weight
FROM expense_budgets
ORDER BY weight desc,from_date ASC;
But i can't find out how to integrate this in a subquery or a join to get a result to get this (if the current date is 2020-09-28) :
id;per_member;maximum;from_date;organization_id;organization_type_id;created_at;updated_at
2;5;5000;NULL;NULL;3;2020-09-14 16:43:52;NULL
3;10;40;NULL;NULL;4;2020-09-14 16:43:52;NULL
4;5;5000;NULL;NULL;5;2020-09-14 16:43:52;2020-09-28 09:46:24
9;15;15000;2020-09-27;NULL;2;2020-09-14 16:43:52;NULL
You got it ? only one record for each organization_type_id with the selected value based on the order made fron the case subquery.
In advance, thank you for your answer
Assuming the combination organization_type_id + from_date is unique:
with lastbudgets as (select eb2.organization_type_id, max(eb2.from_date) as from_date
from expense_budgets eb2
where eb2.from_date is null or eb2.from_date <= now()
group by eb2.organization_type_id)
select eb.*
from expense_budgets eb
inner join lastbudgets lb
on lb.organization_type_id = eb.organization_type_id
and ((lb.from_date is null and eb.from_date is null) or lb.from_date = eb.from_date)
UPDATED: extra logic on null case
You could try to edit your question by adding sample data in this format below:
put in a line containing ```SQL, that's three back-ticks followed by the keyword SQL.
then put in your data in the format I put in below (I ignored create/change timestamp, as they seem irrelevant to the problem). I'm only sure the data is not representative, so you'll have to tweak it to reflect your challenge.
End your "quoted code" input with a line, only containing: ```
```SQL
WITH
expense_budgets(id,per_member,maximum,fromdt,orgid,org_tpid) AS (
SELECT 1,15,15000,DATE '2020-09-12',NULL::INT,2
UNION ALL SELECT 2,20,15000,DATE '2020-09-13',NULL::INT,3
UNION ALL SELECT 3, 5,15000,DATE '2020-09-14',NULL::INT,4
UNION ALL SELECT 4,35,15000,DATE '2020-09-15',NULL::INT,2
UNION ALL SELECT 5, 5,15000,DATE '2020-09-16',NULL::INT,3
UNION ALL SELECT 6,15,15000,DATE '2020-09-17',NULL::INT,4
UNION ALL SELECT 7, 2,15000,DATE '2020-09-18',NULL::INT,2
UNION ALL SELECT 8, 7,15000,DATE '2020-09-19',NULL::INT,3
UNION ALL SELECT 9, 6,15000,DATE '2020-09-20',NULL::INT,4
UNION ALL SELECT 10, 5,15000,DATE '2020-09-21',NULL::INT,2
UNION ALL SELECT 11,35,15000,DATE '2020-09-22',NULL::INT,3
UNION ALL SELECT 12,15,15000,DATE '2020-09-23',NULL::INT,4
)
SELECT * FROM expense_budgets ; -- < replace with real query, please ...
-- ``` un-comment this , (three back-ticks don't display in quoted code ...

SQL Query to find number of users in a Job Area

I have three tables:
jobAreas (id, title)
jobSkills (id,title, jobAreaID)
userSkills (id, userID, jobSkillID)
Each jobSkills entry belongs to a JobArea (linked by foreign key jobAreaID). And each userSkills entry has a JobSkill that is related to a jobSkill.
I am trying to create a SQL select query that will list the number of users that belong to each Job Area.
SELECT ja.id, ja.title, COUNT(*) as numUsers FROM user_skill_types uskills INNER JOIN job_areas ja INNER JOIN skill_types st ON ja.id = st.parent_id GROUP BY ja.id
But the numbers I am getting are not correct.
Given the following example (based on the table structure provided in the question).
CREATE TABLE `jobareas` (
`id` int(11) NOT NULL,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `jobareas` (`id`, `title`) VALUES
(1, 'area1'),
(2, 'area2'),
(3, 'area3'),
(4, 'area4'),
(5, 'area5'),
(6, 'area6'),
(7, 'area7'),
(8, 'area8');
-- --------------------------------------------------------
CREATE TABLE `jobskills` (
`id` int(11) NOT NULL,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`jobAreaID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `jobskills` (`id`, `title`, `jobAreaID`) VALUES
(1, 'skill1', 1),
(2, 'skill2', 3),
(3, 'skill3', 3),
(4, 'skill4', 7),
(5, 'skill5', 4),
(6, 'skill6', 5),
(7, 'skill7', 1),
(8, 'skill8', 7),
(9, 'skill9', 6),
(10, 'skill10', 3),
(11, 'skill11', 4),
(12, 'skill12', 2),
(13, 'skill13', 6),
(14, 'skill14', 7),
(15, 'skill15', 2);
-- --------------------------------------------------------
CREATE TABLE `userskills` (
`id` int(11) NOT NULL,
`userID` int(11) NOT NULL,
`jobSkillID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `userskills` (`id`, `userID`, `jobSkillID`) VALUES
(1, 5, 10),
(2, 2, 11),
(3, 4, 14),
(4, 4, 6),
(5, 2, 8),
(6, 6, 9),
(7, 3, 9),
(8, 1, 12),
(9, 1, 3),
(10, 5, 10);
ALTER TABLE `jobareas`
ADD UNIQUE KEY `id` (`id`);
ALTER TABLE `jobskills`
ADD PRIMARY KEY (`id`),
ADD KEY `jobAreaID` (`jobAreaID`);
ALTER TABLE `userskills`
ADD PRIMARY KEY (`id`),
ADD KEY `userID` (`userID`),
ADD KEY `jobSkillID` (`jobSkillID`);
ALTER TABLE `jobskills`
ADD CONSTRAINT `jobskills_ibfk_1` FOREIGN KEY (`jobAreaID`) REFERENCES `jobareas` (`id`);
ALTER TABLE `userskills`
ADD CONSTRAINT `userskills_ibfk_1` FOREIGN KEY (`jobSkillID`) REFERENCES `jobskills` (`id`);
Your query should use DISTINCT.
SELECT COUNT(DISTINCT(`us`.`userID`)) AS `num`,`ja`.`title` FROM `userskills` `us`
INNER JOIN `jobskills` `js` ON `js`.`id` = `us`.`jobSkillID`
INNER JOIN `jobareas` `ja` ON `ja`.`id` = `js`.`jobAreaID`
GROUP BY `ja`.`id`;
The results can be checked in this SQLFiddle
Your SQL Query shared does not seem to match the schema shared. Also you have not specified how to join the job_areas table
Use
select
ja.id, ja.title , count(us.id) as numUsers
from jobAreas ja
INNER JOIN jobSkills js on ja.id = js.jobAreaID
INNER JOIN userSkills us on js.id = us.jobSkillID
GROUP BY ja.id, ja.title
You are probably getting duplicates in your result because of users having multiple skills or jobs having multiple areas, or both. Rather than COUNT(*), use COUNT(DISTINCT userID) to work around that:
SELECT ja.id, ja.title, COUNT(DISTINCT us.userID) as numUsers
FROM jobAreas ja
JOIN jobSkills js ON js.jobAreaID = ja.id
JOIN userSkills us ON us.jobSkillsID = js.id
GROUP BY ja.id, ja.title
Note I've written the query based on the schema in your question. Based on the query you have written, it should probably look something like (it's not clear what the user_skill_types userID column is called, or how to JOIN user_skill_types to job_skills):
SELECT ja.id, ja.title, COUNT(DISTINCT uskills.userID) as numUsers
FROM job_areas ja
JOIN skill_types st ON ja.id = st.parent_id
JOIN user_skill_types uskills ON uskills.jobSkillID = st.id
GROUP BY ja.id, ja.title

mysql how to sort based on relationship field

i stumbled the following problem that i cannot solve
i have the following table in the database
CREATE TABLE `departments` (
`Company` int(11) NOT NULL,
`Department` varchar(32) NOT NULL,
`DepartmentName` varchar(40) NOT NULL,
`parentDepartment` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `departments` (`Company`, `Department`, `DepartmentName`, `parentDepartment`) VALUES
(1, '1', 'Company1 Ltd', '1'),
(1, '101', 'Information Technology', '1'),
(1, '10101', 'Hardware', '101'),
(1, '10102', 'Software', '101'),
(1, '102', 'Sales Department', '1'),
(1, '10201', 'Travelling', '101');
COMMIT;
basically its a list of departments in the company. Each department can be "nested" under another using the "parentDepartment" field.
Department field is the code of the department. But the numbering is irrelevant to the "structure".
what i want to achieve can be viewed in the picture bellow.
The question is how to sort this table out and keep the relationships visible?
Thank you
Try this:
SELECT *
FROM departments
ORDER BY department;

subquery in IN clause?

I have two tables named as
product_Category
CREATE TABLE `product_category` (
`pid` int(11) NOT NULL,
`cid` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `product_category`
--
/*!40000 ALTER TABLE `product_category` DISABLE KEYS */;
INSERT INTO `product_category` (`pid`,`cid`) VALUES
(1,1),
(2,3),
(3,2),
(4,2),
(5,3),
(1,2),
(2,4),
(3,1);
and category table
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cat_name` varchar(50) NOT NULL,
`mapped_cat_id` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `category`
--
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
INSERT INTO `category` (`id`,`cat_name`,`mapped_cat_id`) VALUES
(1,'c1','1,2,4'),
(2,'c2','2,3'),
(3,'c3','3,4'),
(4,'c4','4,1,3');
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
When I run this query
select distinct pid from
product_category where cid in (1,2,4)
I got result of pid (1,3,4,2)
but when I run query
select distinct pid from
product_category where cid in (select mapped_cat_id from category where id=1)
I got result of pid (1,3)
How to use subquery with 'IN' clause ?
I know my way of asking question is wrong because I dont know how to create table here thats why I wrote query instead of table.
i think coma separated values are not good.
Delete contents of your category table and use following query to insert
INSERT INTO `category` (`id`, `cat_name`, `mapped_cat_id`) VALUES
(1, 'c1', '1'),
(2, 'c2', '2'),
(3, 'c3', '3'),
(4, 'c4', '4'),
(5, 'c1', '2'),
(6, 'c1', '4'),
(7, 'c2', '3'),
(8, 'c3', '4'),
(9, 'c4', '1'),
(10, 'c4', '3');
Then use following query to get your result
select distinct pid from
product_category where cid in
(select mapped_cat_id from category where cat_name='c1')
You might be looking for FIND_IN_SET() function
select distinct pid from
product_category where FIND_IN_SET(cid,
(select mapped_cat_id from category where id=1));
SAMPLE FIDDLE
Since mapped_cat_id is saved as comma - seperated values(varchar), it is taking only first integer for the condition checking. Here it is 1