How to use subqueries in MySQL - sql

I have two tables.
Table user:
CREATE TABLE IF NOT EXISTS `user` (
`user_id` int(20) NOT NULL AUTO_INCREMENT,
`ud_id` varchar(50) NOT NULL,
`name` text NOT NULL,
`password` text NOT NULL,
`email` varchar(200) NOT NULL,
`image` varchar(150) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB
and mycatch:
CREATE TABLE IF NOT EXISTS `mycatch` (
`catch_id` int(11) NOT NULL AUTO_INCREMENT,
`catch_name` text NOT NULL,
`catch_details` text NOT NULL,
`longitude` float(10,6) NOT NULL,
`latitude` float(10,6) NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`image` varchar(150) NOT NULL,
`user_id` int(20) NOT NULL,
PRIMARY KEY (`catch_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB;
ALTER TABLE `mycatch`
ADD CONSTRAINT `mycatch_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
My goal is: I want to retrieve longitude and latitude from mycatch against given ud_id (from user) and catch_id (from mycatch) where ud_id = given ud_id and catch_id > given catch_id.
I used the query but fail to retrieve
SELECT ud_id=$ud_id FROM user
WHERE user_id =
(
SELECT user_id,longitude,latitude from mycatch
WHERE catch_id>'$catch_id'
)
The error is:
#1241 - Operand should contain 1 column(s)

First, try not to use subqueries at all, they're very slow in MySQL.
Second, a subquery wouldn't even help here. This is a regular join (no, Mr Singh, not an inner join):
SELECT ud_id FROM user, mycatch
WHERE catch_id>'$catch_id'
AND user.user_id = mycatch.user_id

Select m.longitude,m.latitude from user u left join mycatch m
on u.user_id =m.user_id
where u.ud_id=$ud_id and
m.catch_id >$catch_id

Related

How to select all records with foreign key?

I have tables that have been created like so:
CREATE TABLE `d_account` (
`id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`account_name` varchar(128) CHARACTER SET utf8 NOT NULL,
`user_id` smallint(5) NOT NULL,
`type_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_account_type` (`type_id`),
CONSTRAINT `FK_type` FOREIGN KEY (`type_id`) REFERENCES `d_types` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE `d_types` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
);
How would I select all records that exist in both tables below using the foreign key where the d_type name equals ‘large’?
That's basically just a JOIN like this:
SELECT * FROM d_types t
JOIN d_account a ON t.id = a.type_id
WHERE t.name = 'large';
The * after select should be replaced by the columns you want to select.

How to turn this query into a typeorm query

How do I transform the query below into a typeorm query? I want to return the count of all the jackets inside each column and have it ordered for a specific board.
SELECT c.id, COUNT(j.id)
FROM `column` c, jacket j
WHERE c.boardId = 1 AND j.columnId = c.id
GROUP BY j.columnId
For these tables
CREATE TABLE IF NOT EXISTS `board` (
`id` int(6) unsigned NOT NULL,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `column` (
`id` int(6) unsigned NOT NULL,
`name` varchar(200) NOT NULL,
`boardId` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (boardId) REFERENCES board(`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `jacket` (
`id` int(6) unsigned NOT NULL,
`description` varchar(200) NOT NULL,
`columnId` int(6) unsigned NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (columnId) REFERENCES `column`(`id`)
) DEFAULT CHARSET=utf8;
Figured out a solution.
const results = await this.connection
.createQueryBuilder()
.select('column.id')
.from(Column, 'column')
.addSelect('COUNT(*)', 'jacketCount')
.from(Jacket, 'jacket')
.where('column.boardId = :id', { id: jacketBoardId })
.where('column.id = jacket.columnId')
.groupBy('column.id')
.orderBy('column.position', 'ASC')
.getRawMany();

SQL find all records from one table, but only the most recent record from a linked table

I am looking to select all records from my userrecords table and then find the corresponding most recent record from my checkins table.
I need to do this so that I can display whether the user is checked-in or checked-out for the current day and campus.
The outdatetime is a NULL value when the user is currently checked-in, and the query should take into account the current date so that only checkin records for the current date are considered.
My table setup is like so:
CREATE TABLE `userrecords` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(45) NOT NULL,
`surname` varchar(45) NOT NULL,
`email` varchar(45) NOT NULL,
`phone` varchar(15) DEFAULT NULL,
`password` char(64) DEFAULT NULL,
`userlevel` int(1) NOT NULL,
`suspended` varchar(1) DEFAULT NULL,
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`lastcheckdate` datetime DEFAULT NULL,
`maincampus` varchar(3) DEFAULT NULL,
`lastlogin` datetime DEFAULT NULL,
`staffid` varchar(6) DEFAULT NULL,
PRIMARY KEY (`userid`),
UNIQUE KEY `email_UNIQUE` (`email`),
UNIQUE KEY `userid_UNIQUE` (`userid`)
) ENGINE=InnoDB AU
CREATE TABLE `checkins` (
`recordid` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`campusid` int(11) NOT NULL,
`indatetime` datetime DEFAULT NULL,
`outdatetime` datetime DEFAULT NULL,
PRIMARY KEY (`recordid`),
KEY `campusid_idx` (`campusid`),
KEY `userid_idx` (`userid`),
CONSTRAINT `campusid` FOREIGN KEY (`campusid`) REFERENCES `campus` (`campusid`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `userid` FOREIGN KEY (`userid`) REFERENCES `userrecords` (`userid`) ON DELETE CASCADE ON UPDATE CASCADE
My query is so far:
SELECT userid,firstname,surname,email,lastcheckdate FROM userrecords WHERE userlevel=0
You can use window functions:
select ur.*, c.*
from userrecords ur left join
(select c.*,
row_number() over (partition by userid order by indatetime desc) as seqnum
from checkins c
) c
on ur.userid = c.userid and ur.seqnum = 1;

Cannot add or update a child row: a foreign key constraint fails (Clubs and Users)

User Table
CREATE TABLE IF NOT EXISTS `users` (
`userId` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`firstname` varchar(25) NOT NULL,
`lastname` varchar(25) NOT NULL,
`email` varchar(50) NOT NULL,
`password` varchar(32) NOT NULL,
`addressLine1` varchar(80) NOT NULL,
`addressLine2` varchar(80) NOT NULL,
`town` varchar(30) NOT NULL,
`county` varchar(30) NOT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=55 ;
Club Table
CREATE TABLE IF NOT EXISTS `clubs` (
`clubId` int(11) NOT NULL AUTO_INCREMENT,
`clubName` varchar(100) NOT NULL,
`startTime` varchar(5) NOT NULL,
`finishTime` varchar(5) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`clubId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
memberid Table
CREATE TABLE IF NOT EXISTS `membersid` (
`memberId` int(11) NOT NULL AUTO_INCREMENT,
`clubId` int(11) NOT NULL,
`userId` int(11) NOT NULL,
PRIMARY KEY (`memberId`,`clubId`,`userId`),
UNIQUE KEY `memberId` (`memberId`),
KEY `clubId` (`clubId`),
KEY `userId` (`userId`),
KEY `clubId_2` (`clubId`),
KEY `clubId_3` (`clubId`),
KEY `userId_2` (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
DAO
String query = "INSERT INTO membersid( userId, clubId ) VALUES ( ?,? )";
Keep getting error Cannot add or update a child row: a foreign key constraint fails
If someone could be that would be great:)
Your keys in the membersid table (please change that name to members) are messed up. Try
CREATE TABLE IF NOT EXISTS members
(
`memberId` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`clubId` int(11) NOT NULL,
`userId` int(11) NOT NULL,
UNIQUE KEY (`clubId`,`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

sql query is returning the same values twice

I have this sql query, and it should be returning two values, which is does but it returns each returned row twice, the sql looks like this,
SELECT * FROM `mailers`
LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailers`.`id` = 26
The table structure for the tables I am query look like this,
-- --------------------------------------------------------
--
-- Table structure for table `mailers`
--
CREATE TABLE `mailers` (
`id` int(11) NOT NULL auto_increment,
`mailer_title` varchar(150) NOT NULL,
`mailer_header` varchar(60) NOT NULL,
`mailer_type` enum('single','multi') NOT NULL,
`introduction` varchar(80) NOT NULL,
`status` enum('live','dead','draft') NOT NULL,
`flag` enum('sent','unsent') NOT NULL,
`date_mailer_created` int(11) NOT NULL,
`date_mailer_updated` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=29 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_content`
--
CREATE TABLE `mailer_content` (
`id` int(11) NOT NULL auto_increment,
`headline` varchar(320) NOT NULL,
`content` text NOT NULL,
`mailer_id` int(11) NOT NULL,
`position` enum('left','right','centre') default NULL,
`tab_1_name` varchar(25) default NULL,
`tab_1_link` varchar(250) default NULL,
`tab_2_name` varchar(25) default NULL,
`tab_2_link` varchar(250) default NULL,
`tab_3_name` varchar(25) default NULL,
`tab_3_link` varchar(250) default NULL,
`tab_4_name` varchar(25) default NULL,
`tab_4_link` varchar(250) default NULL,
`created_at` int(10) NOT NULL,
`updated_at` int(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `mailer_id` (`mailer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_images`
--
CREATE TABLE `mailer_images` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(150) NOT NULL,
`filename` varchar(150) NOT NULL,
`mailer_id` int(11) NOT NULL,
`content_id` int(11) default NULL,
`date_created` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=49 ;
I am sure that is must be a problem with my sql I just do not know what the problem is
If you use SELECT DISTINCT SQL will not return dupplicated rows, if there are some.
SELECT DISTINCT * FROM `mailers` LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id` LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id` WHERE `mailers`.`id` = 26
U can use group by smthng. It will delete the same records.
but u can delete nonsame rows. Use smthng without same values in different rows in original table.
try this
SELECT * FROM mailers
LEFT JOIN mailer_content ON mailers.id = mailer_content.mailer_id
LEFT JOIN mailer_images ON mailer_content.id = mailer_images.content_id
WHERE mailers.id = 26 GROUP BY mailers.id
It doesn't look like an SQL isse to me; I suspect this is more likely down to the data in your tables.
My guess is that there are two rows in mailer_content where mailers.id = 26 and then two rows (or possibly 1 and 3) in mailer_images for each of the mailer_contents.
How many rows do each of the following queries return?
SELECT * FROM `mailers`
WHERE `mailers`.`id` = 26
SELECT * FROM `mailer_content`
WHERE `mailer_content`.`id` = 26
My guess is that the first returns 1 row (because it has a primary key on id) and that the second returns two rows.
That all may be fine but my guess is that the following query returns 4 records:
SELECT * FROM `mailer_content`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailer_content`.`id` = 26
Because either each content has two images each OR one content has one image and the other has three.