我需要一个查询,可以告诉我昨天,前2天和前3天给定idTest的idObj数。
前2天标记的idObj数量应包括idObj标记昨天,即它应该只显示昨天和之前2天标记的idObj的数量。 标记为3天前的idOjb数量应包括标记为昨天,前2天和前3天的idObj。
我还需要列的名称作为日期而不是'DayBeforeYest'和'TwoDayBefore'。
以下是我要找的内容:
idTest 2013-06-29 2013-06-28 2013-06-27
104 9 7 5
105 7 6 2
106 5 3 0
此处,在2013-06-29,idObj计数包括仅在2013-06-29标记的idObj。在2013-06-28,idObj计数包括已在2013-06-29和2013-06-28标记的idObj。在2013-06-27,idObj计数包括已标记的idObj 2013-06-29,2013-06-06和2013-06-27。因此,与昨天相比,3天前列的idObj计数会更少。
查询
create table tblTest (dateFact date, idTest int, idObj int);
insert into tblTest values
('2013-06-29', 104, 4433), ('2013-06-29', 105, 3345), ('2013-06-29', 106, 5543),
('2013-06-28', 104, 4433), ('2013-06-28', 105, 3345), ('2013-06-28', 106, 4356),
('2013-06-27', 104, 3439), ('2013-06-07', 105, 3345), ('2013-06-07', 106, 8955);
以下是我提出的查询,但它只计算每个idTest在第2天和第3天标记的idObj的数量。它没有考虑在流行天数中标记的idObj。它也不以日期格式显示列名。
select idTest, max(Yest) as Yest, max(DayBeforeYest) as DayBeforeYest, max(TwoDayBefore) as TwoDayBefore from
(
(select idTest, count(idObj) as Yest, 0 as DayBeforeYest, 0 as TwoDayBefore from tblTest
where dateFact =date_sub(curdate(), interval 1 day) group by idTest)
union
(select idTest, 0 as Yest, count(idObj) DayBeforeYest, 0 as TwoDayBefore from tblTest
where dateFact = date_Sub(curdate(), interval 2 day) group by idTest)
union
(select idTest, 0 as Yest, 0 as DayBeforeYest , count(idObj) TwoDayBefore from tblTest
where dateFact = date_sub(curdate(), interval 3 day) group by idTest) )x
group by idTest;
谢谢!
====================================
编辑:
create table tblTest (dateFact date, idTest int, idObj int);
INSERT INTO tblTest
select CURDATE() - INTERVAL 1 DAY, 104, 4433 UNION ALL
SELECT CURDATE() - INTERVAL 1 DAY, 105, 3345 UNION ALL
SELECT CURDATE() - INTERVAL 1 DAY, 106, 5543 UNION ALL
SELECT CURDATE() - INTERVAL 2 DAY, 104, 4433 UNION ALL
SELECT CURDATE() - INTERVAL 2 DAY, 105, 3345 UNION ALL
SELECT CURDATE() - INTERVAL 2 DAY, 106, 4356 UNION ALL
SELECT CURDATE() - INTERVAL 3 DAY, 104, 3439 UNION ALL
SELECT CURDATE() - INTERVAL 3 DAY, 105, 3345 UNION ALL
SELECT CURDATE() - INTERVAL 3 DAY, 106, 8955;
对于给定的示例,输出应如下所示:
idTest 2013-06-30 2013-06-29 2013-06-28
104 1 1 0
105 1 1 1
106 1 0 0
在2013-06-30为idTest 104,我们有1个idObj 4433.在2013-06-29为idTest 104,我们有1个idObj 4433,这也是2013-06-30的idTest 104。 在2013-06-28对于idTest 104,我们有1个idObj 3439,它不在2013-06-30或2013-06-29中用于idTest 104.因此,您将看到104的行值为1 1 0。 / p>
在2013-06-30为idTest 105,我们有1个idObj 3345.在2013-06-29为idTest 105,我们有1个idObj 3345,这也是2013-06-30 idTest 105。 在2013-06-28 for idTest 105,我们有1个idObj 3345,也是2013-06-30和2013-06-29。因此,您将看到行值为1 1 1。
等等......
在2013-06-28,计算idObj,它应该出现在2013-06-28,213-06-29,2013-06-30。 在2013-06-29,计算idObj,它应该出现在2013-06-29和2013-06-30。 在2013-06-30,计算idObj,它应该出现在2013-06-30。
答案 0 :(得分:0)
更新要使列名成为日期,您必须使用动态SQL。
SET @sql = CONCAT(
'SELECT idTest
, SUM(d1) `', DATE_FORMAT(CURDATE() - INTERVAL 1 DAY, '%Y-%m-%d'),
'`, SUM(d2 = 1 AND d1 = 1) `', DATE_FORMAT(CURDATE() - INTERVAL 2 DAY, '%Y-%m-%d'),
'`, SUM(d3 = 1 AND d2 = 1 AND d1 = 1) `', DATE_FORMAT(CURDATE() - INTERVAL 3 DAY, '%Y-%m-%d'),
'` FROM
(
SELECT idTest
,idObj
,SUM(CASE WHEN dateFact = CURDATE() - INTERVAL 1 DAY THEN 1 ELSE 0 END) d1
,SUM(CASE WHEN dateFact = CURDATE() - INTERVAL 2 DAY THEN 1 ELSE 0 END) d2
,SUM(CASE WHEN dateFact = CURDATE() - INTERVAL 3 DAY THEN 1 ELSE 0 END) d3
FROM tblTest
WHERE dateFact BETWEEN CURDATE() - INTERVAL 3 DAY AND CURDATE() - INTERVAL 1 DAY
GROUP BY idTest, idObj
) q
GROUP BY idTest');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
示例输出:
| IDTEST | 2013-07-02 | 2013-07-01 | 2013-06-30 | ------------------------------------------------- | 104 | 1 | 1 | 0 | | 105 | 1 | 1 | 1 | | 106 | 1 | 0 | 0 |
这是 SQLFiddle 演示
为了让客户端(调用)方面的生活更轻松,您可以将此代码包装到存储过程中
DELIMITER $$
CREATE PROCEDURE sp_test_report()
BEGIN
-- put above mentioned code here
END$$
DELIMITER ;
然后使用它
CALL sp_test_report();
这是 SQLFiddle 演示