我有两个表,一个是带有DATE列的日历表,另一个是包含每个ID的ID和三个DATES。
日历表:
$stmt = $db->prepare("UPDATE employer
SET name='".$name."', phone='".$phone."',lname='".$lanme."'
WHERE username='".$_SESSION['username']."' ");
数据表:
dt
2016-01-01
2016-01-02
2016-01-03
2016-01-04
...
数据表确实包含许多其他字段,但我认为这与我的问题无关。我有一个查询,它从日历表中选择给定范围的DATE字段,比方说一个月,然后我使用所有三个DATE字段结合OR对数据表进行LEFT JOIN,因为我需要计算多个东西从数据表中,一些取决于d_created,一些取决于d_forwarded和其他d_solved:
ID d_created d_forwarded d_solved
1 2016-01-01 2016-01-02 2016-01-03
2 2016-01-01 2016-01-02 2016-01-03
3 2016-01-02 2016-01-02 2016-01-04
4 2016-01-03 2016-01-04 2016-01-05
...
现在这是我的问题:当我没有通过tc.dt对结果进行分组时,查询会提供正确的输出,但是一旦我将其分组为tc.dt,结果就不正确。我绝不是SQL专家,但据我所知,由于JOIN,td.id将不止一次出现,只要我有一个结果行,DISTINCT就会阻止ID被计算两次
我需要能够计算在我的日期范围内创建,解决或转发的所有ID,并且我还需要日历表连接,因为我想在范围内显示每一天,即使可能存在如果有意义的话,我的数据表中没有特定日期的匹配日期。
有什么方法可以确保在按日分组时,不会多次计算任何ID?
我希望我能说清楚究竟是什么问题,如果没有,请告诉我,我会详细说明。
更新 我尝试使用SarathChandra示例,它看起来非常有前途,它确实提供了结果,但是只要我在CASE WHEN语句中添加更多条件,它就不会按预期方式工作。我分叉并修改了SarathChandra的想法小提琴HERE
所以它应该在2016-01-02日期返回1,但它显示0?
更新2 不幸的是,所提供的答案都没有能够解决潜在的问题。虽然这两个建议都得到了很多赞赏,但我最终将查询拆分为三个查询,每次都使用相同的日期范围加入日历表,然后将PHP中的数组合并到一个结果集中。
答案 0 :(得分:0)
这里的问题是您加入了多个列,因此当您按日期分组时,您可以获得&#39> 2016-01-01&#的 ID 1 39; (已创建),' 2016-01-02' (已解决)和' 2016-01-03' (转发)。
您可以尝试连接同一个表3次,并将结果计入3列。然后,每列的总和应与记录数相匹配。
查询:
SELECT tc.dt AS dt,
COUNT(DISTINCT(CASE WHEN td_solved.id != 0
AND DATE(td_solved.d_solved) >= '2016-01-01'
AND DATE(td_solved.d_solved) <= '2016-01-31' THEN td_solved.id ELSE NULL END)) AS solved,
COUNT(DISTINCT(CASE WHEN td_created.id != 0
AND DATE(td_created.d_created) >= '2016-01-01'
AND DATE(td_created.d_created) <= '2016-01-31' THEN td_created.id ELSE NULL END)) AS created,
COUNT(DISTINCT(CASE WHEN td_forwarded.id != 0
AND DATE(td_forwarded.d_forwarded) >= '2016-01-01'
AND DATE(td_forwarded.d_forwarded) <= '2016-01-31' THEN td_forwarded.id ELSE NULL END)) AS forwarded
FROM calendar_table tc
LEFT JOIN data_table td_created ON tc.dt = DATE(td_created.d_created)
LEFT JOIN data_table td_solved ON tc.dt = DATE(td_solved.d_solved)
LEFT JOIN data_table td_forwarded ON tc.dt = DATE(td_forwarded.d_forwarded)
GROUP BY 1 WITH ROLLUP
答案 1 :(得分:0)
我在得出以下解决方案时对数据做了一些假设:
d_created
应位于d_forwarded
之前,而d_solved
则先于SELECT
tc.dt AS dt,
COUNT(
CASE WHEN DATE(td.d_created) BETWEEN '2016-01-01' AND '2016-01-31' THEN td.id
ELSE NULL END) AS `Count`
FROM calendar_table tc
LEFT JOIN data_table td ON
(tc.dt = LEAST(DATE(td.d_created), DATE(td.d_solved), DATE(td.d_forwarded)))
GROUP BY tc.dt;
。 以下查询似乎对我有用。
.TSS {
border: 1px solid #000000;
float: none;
font-family: Verdana, Geneva, sans-serif;
font-size: 10.6px;
font-style: normal;
padding: 10px;
text-decoration: none;
display: inline-block;
}
#centertbl {
text-align: center;
}
.button {
background-color: #4CAF50;
/* Green */
border: none;
color: white;
padding: 5px 15px;
text-align: center;
text-decoration: none;
display: block;
font-size: 16px;
margin: 4px 2px;
-webkit-transition-duration: 0.4s;
/* Safari */
transition-duration: 0.4s;
cursor: pointer;
}
.button1 {
background-color: white;
color: black;
border: 2px solid #4CAF50;
}
.button1:hover {
background-color: #4CAF50;
color: white;
}
.images-area {
position: relative;
margin: 0 0 15px;
}
.red-square {
display: block;
margin: 0 auto;
}
.black-circles {
position: absolute;
margin-top: -60px;
left: 10px;
top: 50%;
}
.black-circles img {
margin: 0 0 -15px;
max-width: 100%;
display: block;
height: auto;
}
更新:工作示例代码here。