LEFT JOIN select 左联接的最新行
LEFT JOIN select latest row from the left join
我有一个公司数据库,其中包含所有详细信息。它还有一个单独的 table 存储信用评级。
DROP TABLE IF EXISTS `company`;
CREATE TABLE IF NOT EXISTS `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET latin1 NOT NULL,
`email` varchar(255) CHARACTER SET latin1 NOT NULL,
`address` varchar(255) NOT NULL,
`address2` text NOT NULL,
`address3` text NOT NULL,
`phone` text NOT NULL,
`contacts` text NOT NULL,
`islive` tinyint(1) NOT NULL DEFAULT '1',
`qt` tinyint(1) NOT NULL DEFAULT '30',
`pt` tinyint(1) NOT NULL DEFAULT '30',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `creditrating`;
CREATE TABLE IF NOT EXISTS `creditrating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cid` int(11) NOT NULL,
`rating` int(11) NOT NULL,
`arating` varchar(10) NOT NULL,
`type` tinyint(1) NOT NULL DEFAULT '1',
`thedate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `company` (`id`, `name`, `email`, `address`, `address2`, `address3`, `phone`, `contacts`, `islive`, `qt`, `pt`) VALUES
(190, 'Test Company', 'test@test.com', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name', 1, 30, 30),
(191, 'Test Company 2', 'test2@test2.com', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name 2', 1, 30, 30);
INSERT INTO `creditrating` (`id`, `cid`, `rating`, `arating`, `type`, `thedate`) VALUES
(3, 190, 684, 'da774', 1, '2021-03-30 15:08:52'),
(6, 190, 222, 'DD222', 1, '2021-03-30 17:46:22');
我试图只检索公司详细信息和信用评级的最新行 table。
我最接近让它工作的 SQL 是 (Mysql 5.6):
SELECT c.id
, AES_DECRYPT(c.name, 'co1') as name
, AES_DECRYPT(c.phone, 'co3') as phone
, c.islive
, r.rating
FROM company c
LEFT
JOIN creditrating r
ON (SELECT r.thedate FROM creditrating WHERE c.id=r.cid ORDER BY r.thedate DESC LIMIT 1)
目前它正在带回同一家公司的 2 行,而不仅仅是 1 行。
在此先感谢大家对我的指导。
您可以为此使用 window 函数:
SELECT c.id, AES_DECRYPT(c.name, 'co1') as name, AES_DECRYPT(c.phone, 'co3') as phone, c.islive, r.rating
FROM company c LEFT JOIN
(SELECT r.*,
ROW_NUMBER() OVER (PARTITION BY r.cid ORDER BY r.thedate DESC) as seqnum
FROM creditrating r
) r
ON c.id = r.cid AND r.seqnum = 1;
以前的版本没有 window 函数,但您可以切换到用户定义的变量
DROP TABLE IF EXISTS `company`;
CREATE TABLE IF NOT EXISTS `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET latin1 NOT NULL,
`email` varchar(255) CHARACTER SET latin1 NOT NULL,
`address` varchar(255) NOT NULL,
`address2` text NOT NULL,
`address3` text NOT NULL,
`phone` text NOT NULL,
`contacts` text NOT NULL,
`islive` tinyint(1) NOT NULL DEFAULT '1',
`qt` tinyint(1) NOT NULL DEFAULT '30',
`pt` tinyint(1) NOT NULL DEFAULT '30',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `creditrating`;
CREATE TABLE IF NOT EXISTS `creditrating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cid` int(11) NOT NULL,
`rating` int(11) NOT NULL,
`arating` varchar(10) NOT NULL,
`type` tinyint(1) NOT NULL DEFAULT '1',
`thedate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `company` (`id`, `name`, `email`, `address`, `address2`, `address3`, `phone`, `contacts`, `islive`, `qt`, `pt`) VALUES
(190, 'Test Company', 'test@test.com', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name', 1, 30, 30),
(191, 'Test Company 2', 'test2@test2.com', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name 2', 1, 30, 30);
INSERT INTO `creditrating` (`id`, `cid`, `rating`, `arating`, `type`, `thedate`) VALUES
(3, 190, 684, 'da774', 1, '2021-03-30 15:08:52'),
(6, 190, 222, 'DD222', 1, '2021-03-30 17:46:22');
SELECT
id, name, phone, islive, rating, `thedate`
FROM
(SELECT
name,
phone,
islive,
rating,
`thedate`,
IF(id = @id, @rnk:=@rnk + 1, @rnk:=1) AS rnk,
@id:=id AS id
FROM
(SELECT
c.id,
AES_DECRYPT(c.name, 'co1') AS name,
AES_DECRYPT(c.phone, 'co3') AS phone,
c.islive,
r.rating,
`thedate`
FROM
company c
LEFT JOIN creditrating r ON c.id = r.cid) t1, (SELECT @id:=- 1, @rnk:=0) t2
ORDER BY id , `thedate` DESC) t3
WHERE
rnk = 1;
id | name | phone | islive | rating | thedate
--: | :--- | :---- | -----: | -----: | :------------------
190 | null | null | 1 | 222 | 2021-03-30 17:46:22
191 | null | null | 1 | null | null
db<>fiddle here
我有一个公司数据库,其中包含所有详细信息。它还有一个单独的 table 存储信用评级。
DROP TABLE IF EXISTS `company`;
CREATE TABLE IF NOT EXISTS `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET latin1 NOT NULL,
`email` varchar(255) CHARACTER SET latin1 NOT NULL,
`address` varchar(255) NOT NULL,
`address2` text NOT NULL,
`address3` text NOT NULL,
`phone` text NOT NULL,
`contacts` text NOT NULL,
`islive` tinyint(1) NOT NULL DEFAULT '1',
`qt` tinyint(1) NOT NULL DEFAULT '30',
`pt` tinyint(1) NOT NULL DEFAULT '30',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `creditrating`;
CREATE TABLE IF NOT EXISTS `creditrating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cid` int(11) NOT NULL,
`rating` int(11) NOT NULL,
`arating` varchar(10) NOT NULL,
`type` tinyint(1) NOT NULL DEFAULT '1',
`thedate` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `company` (`id`, `name`, `email`, `address`, `address2`, `address3`, `phone`, `contacts`, `islive`, `qt`, `pt`) VALUES
(190, 'Test Company', 'test@test.com', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name', 1, 30, 30),
(191, 'Test Company 2', 'test2@test2.com', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name 2', 1, 30, 30);
INSERT INTO `creditrating` (`id`, `cid`, `rating`, `arating`, `type`, `thedate`) VALUES
(3, 190, 684, 'da774', 1, '2021-03-30 15:08:52'),
(6, 190, 222, 'DD222', 1, '2021-03-30 17:46:22');
我试图只检索公司详细信息和信用评级的最新行 table。
我最接近让它工作的 SQL 是 (Mysql 5.6):
SELECT c.id
, AES_DECRYPT(c.name, 'co1') as name
, AES_DECRYPT(c.phone, 'co3') as phone
, c.islive
, r.rating
FROM company c
LEFT
JOIN creditrating r
ON (SELECT r.thedate FROM creditrating WHERE c.id=r.cid ORDER BY r.thedate DESC LIMIT 1)
目前它正在带回同一家公司的 2 行,而不仅仅是 1 行。
在此先感谢大家对我的指导。
您可以为此使用 window 函数:
SELECT c.id, AES_DECRYPT(c.name, 'co1') as name, AES_DECRYPT(c.phone, 'co3') as phone, c.islive, r.rating
FROM company c LEFT JOIN
(SELECT r.*,
ROW_NUMBER() OVER (PARTITION BY r.cid ORDER BY r.thedate DESC) as seqnum
FROM creditrating r
) r
ON c.id = r.cid AND r.seqnum = 1;
以前的版本没有 window 函数,但您可以切换到用户定义的变量
DROP TABLE IF EXISTS `company`; CREATE TABLE IF NOT EXISTS `company` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET latin1 NOT NULL, `email` varchar(255) CHARACTER SET latin1 NOT NULL, `address` varchar(255) NOT NULL, `address2` text NOT NULL, `address3` text NOT NULL, `phone` text NOT NULL, `contacts` text NOT NULL, `islive` tinyint(1) NOT NULL DEFAULT '1', `qt` tinyint(1) NOT NULL DEFAULT '30', `pt` tinyint(1) NOT NULL DEFAULT '30', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `creditrating`; CREATE TABLE IF NOT EXISTS `creditrating` ( `id` int(11) NOT NULL AUTO_INCREMENT, `cid` int(11) NOT NULL, `rating` int(11) NOT NULL, `arating` varchar(10) NOT NULL, `type` tinyint(1) NOT NULL DEFAULT '1', `thedate` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `company` (`id`, `name`, `email`, `address`, `address2`, `address3`, `phone`, `contacts`, `islive`, `qt`, `pt`) VALUES (190, 'Test Company', 'test@test.com', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 1\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name', 1, 30, 30), (191, 'Test Company 2', 'test2@test2.com', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', 'Testing Client 2\r\nsdfsdfsdf\r\nsdfsdfsdf', '65165156', 'test name 2', 1, 30, 30); INSERT INTO `creditrating` (`id`, `cid`, `rating`, `arating`, `type`, `thedate`) VALUES (3, 190, 684, 'da774', 1, '2021-03-30 15:08:52'), (6, 190, 222, 'DD222', 1, '2021-03-30 17:46:22');
SELECT id, name, phone, islive, rating, `thedate` FROM (SELECT name, phone, islive, rating, `thedate`, IF(id = @id, @rnk:=@rnk + 1, @rnk:=1) AS rnk, @id:=id AS id FROM (SELECT c.id, AES_DECRYPT(c.name, 'co1') AS name, AES_DECRYPT(c.phone, 'co3') AS phone, c.islive, r.rating, `thedate` FROM company c LEFT JOIN creditrating r ON c.id = r.cid) t1, (SELECT @id:=- 1, @rnk:=0) t2 ORDER BY id , `thedate` DESC) t3 WHERE rnk = 1;
id | name | phone | islive | rating | thedate --: | :--- | :---- | -----: | -----: | :------------------ 190 | null | null | 1 | 222 | 2021-03-30 17:46:22 191 | null | null | 1 | null | null
db<>fiddle here