我想从mysql db中获取记录。我想从记录中获取第二个最大日期。但我失败了
这是我的代码
<?php
include ("connection.php");
$q_opinion="SELECT r.client_id,c.id,t.id,a.id,o.id,c.name as opinion, r.notification_date, t.title as ttitle,a.title as atitle,o.title as otitle, l.title as ltitle, s.title as stitle, pr.opinion_id, pc.id, pr.client_id as pr_client, pc.address, pc.liaison_one, city.id, pc.head_office_id, city.city, pc.title as cname
FROM og_ratings r
LEFT join
(
select max(notification_date) notification_date,
client_id
from og_ratings
WHERE notification_date NOT IN (select max(notification_date) FROM og_ratings )
) r2
on r.notification_date = r2.notification_date
and r.client_id = r2.client_id
LEFT JOIN og_companies c
ON r.client_id = c.id
LEFT JOIN og_rating_types t
ON r.rating_type_id = t.id
LEFT JOIN og_actions a
ON r.pacra_action = a.id
LEFT JOIN og_outlooks o
ON r.pacra_outlook = o.id
LEFT JOIN og_lterms l
ON r.pacra_lterm = l.id
LEFT JOIN og_sterms s
ON r.pacra_sterm = s.id
LEFT JOIN pacra_client_opinion_relations pr
ON pr.opinion_id = c.id
LEFT JOIN pacra_clients pc
ON pc.id = pr.client_id
LEFT JOIN city
ON city.id = pc.head_office_id
WHERE r.client_id IN (SELECT opinion_id FROM pacra_client_opinion_relations WHERE client_id = 50)
";
$result = mysql_query($q_opinion) or die;
$rating = array();
while($row = mysql_fetch_assoc($result))
{
$rating[] = $row['client_id'];
$action[] = $row['atitle'];
$opinion[] = $row['opinion'];
$date[] = $row['notification_date'];
$lrating[] = $row['ltitle'];
$srating[] = $row['stitle'];
}
for ($i=0; $i<count($rating); $i++) {
if ($rating[$i] == "")continue;
?>
<table border="1">
<tr>
<td><?= $rating[$i] ?> </td>
<td><?= $date[$i] ?> </td>
<td><?= $opinion[$i] ?> </td>
<td><?= $action[$i] ?> </td>
<td><?= $lrating[$i] ?> </td>
<td><?= $srating[$i] ?> </td>
</tr>
</table>
<?php
}
?>
这是此代码的输出
在输出图像中,您可以看到它从db获取所有记录。但我想只获取具有第二个最大日期的数据。
我怎么做?
答案 0 :(得分:8)
阅读您的查询并不好玩,但我认为问题在于:
LEFT JOIN (
SELECT max(notification_date) notification_date, client_id
FROM og_ratings
WHERE notification_date NOT IN (
SELECT max(notification_date)
FROM og_ratings
)
如果您想要GROUP BY client_id所需的每个客户的最长日期:
SELECT client_id, max(notification_date) notification_date
FROM og_ratings
GROUP BY client_id
如果您想要第二个最大值,那么选项很少,我使用的这个更容易理解,但它不一定是性能最高的:
SELECT client_id, max(notification_date) notification_date
FROM og_ratings
WHERE
(client_id, notification_date) NOT IN (
SELECT client_id, max(notification_date)
FROM og_ratings GROUP BY client_id
)
GROUP BY client_id
第三个问题,你正在使用LEFT JOIN,这意味着你将从og_ratings返回所有值,无论它们是否是第二个最大值。在此上下文中使用INNER JOIN:
SELECT
r.client_id,
c.id,
t.id,
..etc...
FROM
og_ratings r INNER JOIN (
SELECT client_id, max(notification_date) notification_2nd_date
FROM og_ratings
WHERE
(client_id, notification_date) NOT IN (
SELECT client_id, max(notification_date)
FROM og_ratings GROUP BY client_id
)
GROUP BY client_id
) r2
ON r.notification_date = r2.notification_2nd_date
AND r.client_id = r2.client_id
LEFT JOIN og_companies c ON r.client_id = c.id
LEFT JOIN og_rating_types t ON r.rating_type_id = t.id
LEFT JOIN og_actions a ON r.pacra_action = a.id
LEFT JOIN og_outlooks o ON r.pacra_outlook = o.id
LEFT JOIN og_lterms l ON r.pacra_lterm = l.id
LEFT JOIN og_sterms s ON r.pacra_sterm = s.id
LEFT JOIN pacra_client_opinion_relations pr ON pr.opinion_id = c.id
LEFT JOIN pacra_clients pc ON pc.id = pr.client_id
LEFT JOIN city ON city.id = pc.head_office_id
WHERE
r.client_id IN (
SELECT opinion_id FROM pacra_client_opinion_relations
WHERE client_id = 50
)
答案 1 :(得分:2)
请注意,架构设置QueryA
和QueryB
都只是用于可视化。
然而,QueryC
是您尝试使用数据的地方。
这不是一个简单的order
by和limit
@Musa做的原因很简单:你可以拥有许多第二个最大日期的行,而不是一个。这就是为什么使用@grp和@preate的变量来定位第二组。
-- drop table specimenA;
create table specimenA
( mypk int auto_increment primary key,
id int not null, -- note, not autoinc or pk
theDate date not null,
title varchar(255) not null,
otherThing varchar(20) not null
-- etc
-- not other indexes whatsoever
);
-- truncate table specimenA
insert specimenA (id,theDate,title,otherThing) values
(170,'2007-09-19','whatever','whatever'),
(170,'2008-09-12','whatever','whatever'),
(170,'2010-01-15','whatever','whatever'),
(170,'2011-02-03','whatever','whatever'),
(170,'2012-06-26','whatever','whatever'),
(170,'2013-03-05','whatever','whatever'),
(170,'2014-06-25','whatever','whatever'),
(170,'2015-06-09','whatever','whatever'),
(917,'2009-10-14','whatever','whatever'),
(917,'2008-12-31','whatever','whatever'),
(109,'2010-04-26','whatever','whatever'),
(109,'2011-03-02','whatever','whatever'),
(109,'2012-06-25','whatever','whatever'),
(109,'2013-01-04','whatever','whatever'),
(109,'2014-03-28','whatever','whatever'),
(109,'2015-03-18','whatever','whatever'),
(1057,'2014-03-28','whatever','whatever'),
(1057,'2014-11-21','whatever','whatever'),
(1057,'2015-08-13','whatever','whatever');
set @rn:=0,@grp:=0,@prevdate:='';
select id,theDate,title,otherThing,
@rn:=@rn+1 as rownum,
@grp:=if(@prevdate=theDate,@grp,@grp+1) as descGrp,
@prevdate:=theDate as unused
from specimenA
order by theDate DESC -- **** Note this
-- DESC means greatest first, as is most-recent first for dates
+------+------------+----------+------------+--------+---------+------------+
| id | theDate | title | otherThing | rownum | descGrp | unused |
+------+------------+----------+------------+--------+---------+------------+
| 1057 | 2015-08-13 | whatever | whatever | 1 | 1 | 2015-08-13 |
| 170 | 2015-06-09 | whatever | whatever | 2 | 2 | 2015-06-09 |
| 109 | 2015-03-18 | whatever | whatever | 3 | 3 | 2015-03-18 |
| 1057 | 2014-11-21 | whatever | whatever | 4 | 4 | 2014-11-21 |
| 170 | 2014-06-25 | whatever | whatever | 5 | 5 | 2014-06-25 |
| 1057 | 2014-03-28 | whatever | whatever | 6 | 6 | 2014-03-28 |
| 109 | 2014-03-28 | whatever | whatever | 7 | 6 | 2014-03-28 |
| 170 | 2013-03-05 | whatever | whatever | 8 | 7 | 2013-03-05 |
| 109 | 2013-01-04 | whatever | whatever | 9 | 8 | 2013-01-04 |
| 170 | 2012-06-26 | whatever | whatever | 10 | 9 | 2012-06-26 |
| 109 | 2012-06-25 | whatever | whatever | 11 | 10 | 2012-06-25 |
| 109 | 2011-03-02 | whatever | whatever | 12 | 11 | 2011-03-02 |
| 170 | 2011-02-03 | whatever | whatever | 13 | 12 | 2011-02-03 |
| 109 | 2010-04-26 | whatever | whatever | 14 | 13 | 2010-04-26 |
| 170 | 2010-01-15 | whatever | whatever | 15 | 14 | 2010-01-15 |
| 917 | 2009-10-14 | whatever | whatever | 16 | 15 | 2009-10-14 |
| 917 | 2008-12-31 | whatever | whatever | 17 | 16 | 2008-12-31 |
| 170 | 2008-09-12 | whatever | whatever | 18 | 17 | 2008-09-12 |
| 170 | 2007-09-19 | whatever | whatever | 19 | 18 | 2007-09-19 |
+------+------------+----------+------------+--------+---------+------------+
并且,使用上面的select语句,并将其作为别名inR
作为派生表,嵌套:
set @rn:=0,@grp:=0,@prevdate:='';
select id,theDate,title,otherthing
from
( select id,theDate,title,otherThing,
@rn:=@rn+1 as rownum,
@grp:=if(@prevdate=theDate,@grp,@grp+1) as descGrp,
@prevdate:=theDate as unused
from specimenA
order by theDate DESC -- **** Note this
) inR
where descGrp=2;
+-----+------------+----------+------------+
| id | theDate | title | otherthing |
+-----+------------+----------+------------+
| 170 | 2015-06-09 | whatever | whatever |
+-----+------------+----------+------------+
还有你的第二个最伟大的约会。意思是第二个最近的日期。
所以,采取你原来的选择陈述,相同的概念。显示上述内容的动机很简单:InR
只是Derived Table
,不会比您的select语句更多或更少,它将成为派生表。
set @rn:=0,@grp:=0,@prevdate:='';
select client_id, cid, tid, aid, oid, opinion, notification_date,
ttitle, atitle, otitle, ltitle, stitle,
opinion_id, pcid, pr_client, address, liaison_one,
cityid, head_office_id, city, cname
from
( SELECT r.client_id as client_id,c.id as cid,t.id as tid,a.id as aid,o.id as oid,c.name as opinion, r.notification_date,
t.title as ttitle,a.title as atitle,o.title as otitle, l.title as ltitle, s.title as stitle,
pr.opinion_id, pc.id as pcid, pr.client_id as pr_client, pc.address, pc.liaison_one,
city.id as cityid, pc.head_office_id, city.city, pc.title as cname,
@rn:=@rn+1 as rownum,
@grp:=if(@prevdate=r.notification_date,@grp,@grp+1) as descGrp,
@prevdate:=r.notification_date as unused
FROM og_ratings r
LEFT join
(
select max(notification_date) notification_date,
client_id
from og_ratings
WHERE notification_date NOT IN (select max(notification_date) FROM og_ratings )
) r2
on r.notification_date = r2.notification_date
and r.client_id = r2.client_id
LEFT JOIN og_companies c
ON r.client_id = c.id
LEFT JOIN og_rating_types t
ON r.rating_type_id = t.id
LEFT JOIN og_actions a
ON r.pacra_action = a.id
LEFT JOIN og_outlooks o
ON r.pacra_outlook = o.id
LEFT JOIN og_lterms l
ON r.pacra_lterm = l.id
LEFT JOIN og_sterms s
ON r.pacra_sterm = s.id
LEFT JOIN pacra_client_opinion_relations pr
ON pr.opinion_id = c.id
LEFT JOIN pacra_clients pc
ON pc.id = pr.client_id
LEFT JOIN city
ON city.id = pc.head_office_id
WHERE r.client_id IN (SELECT opinion_id FROM pacra_client_opinion_relations WHERE client_id = 50)
order by r.notification_date DESC
) inR
where descGrp=2
您使用的是QueryC。因为这是两个陈述
...你需要按顺序运行查询,每个按顺序运行一次,或者使用PHP multi-query并在一次调用中组合两者。上一句话中的那个链接是针对mysqli的,这个概念在此显示,并据此进行修改。
答案 2 :(得分:2)
您可以使用下面的查询来获取表格中的第二个最大日期或您的要求: -
select joiningDate from t_member order by joiningDate desc limit 1,1
答案 3 :(得分:1)
您可以使用ORDER BY DATE_COLUMN DESC LIMIT 1 OFFSET 1
。我在查询结尾添加了此代码:
SELECT
r.client_id,
c.id,
t.id,
a.id,
o.id,
c.name as opinion,
r.notification_date,
t.title as ttitle,
a.title as atitle,
o.title as otitle,
l.title as ltitle,
s.title as stitle,
pr.opinion_id,
pc.id,
pr.client_id as pr_client,
pc.address,
pc.liaison_one,
city.id,
pc.head_office_id,
city.city,
pc.title as cname
FROM og_ratings r
LEFT join (
select max(notification_date) notification_date,
client_id
from og_ratings
WHERE notification_date NOT IN (select max(notification_date) FROM og_ratings )
) r2
on r.notification_date = r2.notification_date
and r.client_id = r2.client_id
LEFT JOIN og_companies c
ON r.client_id = c.id
LEFT JOIN og_rating_types t
ON r.rating_type_id = t.id
LEFT JOIN og_actions a
ON r.pacra_action = a.id
LEFT JOIN og_outlooks o
ON r.pacra_outlook = o.id
LEFT JOIN og_lterms l
ON r.pacra_lterm = l.id
LEFT JOIN og_sterms s
ON r.pacra_sterm = s.id
LEFT JOIN pacra_client_opinion_relations pr
ON pr.opinion_id = c.id
LEFT JOIN pacra_clients pc
ON pc.id = pr.client_id
LEFT JOIN city
ON city.id = pc.head_office_id
WHERE
r.client_id IN (
SELECT opinion_id FROM pacra_client_opinion_relations WHERE client_id = 50
)
ORDER BY r.notification_date DESC # Add this line
LIMIT 1 offset 1 # and this line