我想要从8月1日到8月31日获取所有行但限制为1500行,但是,它必须包括从1到31的所有可能天数。所以从每天我预计大约48行。
SQL Query如何实现?
我已尝试过这个SQL查询,但它不会包含所有日期,因为我使用的是limit
。
SELECT * FROM table1
WHERE `submit` >= '2014-08-01' AND `submit` <= '2014-08-31'
order by `submit`
LIMIT 1500
更新
它应该从1到31获得所有可能的天数,如果任何天没有足够的行 - 那么包括任何天的剩余行。例如,如果8月7日没有记录,那么任何其他日子都应该包含更多行。
UPDATE2:
假设submit >= '2014-08-01' AND submit <= '2014-08-31'
有3000行,但我只想要从01到31的1000行(如果可能的话)。
每天应该有大约32行。
例如
8月01日有32行
8月02日有32行
08年8月只有0行
08年8月只有0行
05年8月有32行
到
8月31日有32行
答案 0 :(得分:0)
这是一个麻烦的要求,因为它要求在不可预测的情况下无法预测数据的遗漏。这是给审计员带来坏梦的事情(更不用说程序员了)。它可以帮助您弄清楚您要对此结果集做些什么,并收紧您的要求。
假设您的表具有自动递增的唯一id
列,这里的查询将从表中检索每个日期的最后一行。
SELECT 0 AS priority, t.* FROM table1 AS t
WHERE id IN (SELECT MAX(id) AS id FROM table1 GROUP BY DATE(submit))
然后,您可以执行此操作以获取剩余的行:
SELECT 1 AS priority, t.* FROM table1 AS t
WHERE id NOT IN (SELECT MAX(id) AS id FROM table1 GROUP BY DATE(submit))
您可以将这些联合起来,对它们进行排序并限制它们。
SELECT *
FROM (
SELECT 0 AS priority, t.* FROM table1 AS t
WHERE id IN (SELECT MAX(id) AS id FROM table1 GROUP BY DATE(submit))
UNION ALL
SELECT 1 AS priority, t.* FROM table1 AS t
WHERE id NOT IN (SELECT MAX(id) AS id FROM table1 GROUP BY DATE(submit))
) AS results
ORDER BY priority, submit
LIMIT 1500
这将为您提供每个submit
日期至少一行,然后是其余行,但不会超过1500.但是,它不会尝试平衡每个日期的行数。
答案 1 :(得分:0)
步骤1.数据表......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,dt DATE NOT NULL
);
INSERT INTO my_table (dt) VALUES
('2014-07-28'),
('2014-07-29'),
('2014-08-01'),
('2014-08-01'),
('2014-08-02'),
('2014-08-03'),
('2014-08-05'),
('2014-08-05'),
('2014-08-05'),
('2014-08-05'),
('2014-08-07'),
('2014-08-07'),
('2014-08-09'),
('2014-08-10'),
('2014-08-10'),
('2014-08-10'),
('2014-08-11'),
('2014-08-13'),
('2014-08-13'),
('2014-08-13'),
('2014-08-13'),
('2014-08-13'),
('2014-08-13'),
('2014-08-14'),
('2014-08-14'),
('2014-08-15'),
('2014-08-17'),
('2014-08-17'),
('2014-08-18'),
('2014-08-18'),
('2014-08-18'),
('2014-08-19'),
('2014-08-19'),
('2014-08-21'),
('2014-08-21'),
('2014-08-21'),
('2014-08-21'),
('2014-08-22'),
('2014-08-23'),
('2014-08-25'),
('2014-08-25'),
('2014-08-26'),
('2014-08-26'),
('2014-08-26'),
('2014-08-27'),
('2014-08-28'),
('2014-08-29'),
('2014-08-29'),
('2014-08-29'),
('2014-08-29'),
('2014-08-29'),
('2014-08-30'),
('2014-08-31'),
('2014-08-31');
SELECT * FROM my_table;
+----+------------+
| id | dt |
+----+------------+
| 1 | 2014-07-28 |
| 2 | 2014-07-29 |
| 3 | 2014-08-01 |
| 4 | 2014-08-01 |
| 5 | 2014-08-02 |
| 6 | 2014-08-03 |
| 7 | 2014-08-05 |
| 8 | 2014-08-05 |
| 9 | 2014-08-05 |
| 10 | 2014-08-05 |
| 11 | 2014-08-07 |
| 12 | 2014-08-07 |
| 13 | 2014-08-09 |
| 14 | 2014-08-10 |
| 15 | 2014-08-10 |
| 16 | 2014-08-10 |
...
...
| 44 | 2014-08-26 |
| 45 | 2014-08-27 |
| 46 | 2014-08-28 |
| 47 | 2014-08-29 |
| 48 | 2014-08-29 |
| 49 | 2014-08-29 |
| 50 | 2014-08-29 |
| 51 | 2014-08-29 |
| 52 | 2014-08-30 |
| 53 | 2014-08-31 |
| 54 | 2014-08-31 |
+----+------------+
步骤2.包含所有可想到的日期的日历实用程序表...(还有其他方法可以执行此操作,但是 - 异常 - 此问题需要在MySQL中进行,而不是在后处理中)< / p>
SELECT *
FROM calendar
WHERE dt BETWEEN '2014-07-28' AND '2014-09-02';
+------------+
| dt |
+------------+
| 2014-07-28 |
| 2014-07-29 |
| 2014-07-30 |
| 2014-07-31 |
| 2014-08-01 |
| 2014-08-02 |
| 2014-08-03 |
| 2014-08-04 |
| 2014-08-05 |
| 2014-08-06 |
| 2014-08-07 |
| 2014-08-08 |
| 2014-08-09 |
| 2014-08-10 |
| 2014-08-11 |
| 2014-08-12 |
| 2014-08-13 |
| 2014-08-14 |
| 2014-08-15 |
| 2014-08-16 |
| 2014-08-17 |
| 2014-08-18 |
| 2014-08-19 |
| 2014-08-20 |
| 2014-08-21 |
| 2014-08-22 |
| 2014-08-23 |
| 2014-08-24 |
| 2014-08-25 |
| 2014-08-26 |
| 2014-08-27 |
| 2014-08-28 |
| 2014-08-29 |
| 2014-08-30 |
| 2014-08-31 |
| 2014-09-01 |
| 2014-09-02 |
+------------+
37 rows in set
步骤3.查询(保证每天至少一个结果,总体上不超过50个结果)
SELECT dt FROM
(
SELECT a.dt
, COALESCE(rank,0)
FROM calendar a
LEFT
JOIN
( SELECT x.dt,COUNT(*) rank
FROM my_table x
JOIN my_table y
ON y.dt = x.dt
AND y.id <= x.id
GROUP
BY x.id
) b
ON b.dt = a.dt
WHERE a.dt BETWEEN '2014-08-01' AND '2014-08-31'
ORDER
BY rank,dt
LIMIT 50
)n
ORDER BY dt;
+------------+
| dt |
+------------+
| 2014-08-01 |
| 2014-08-01 |
| 2014-08-02 |
| 2014-08-03 |
| 2014-08-04 |
| 2014-08-05 |
| 2014-08-05 |
| 2014-08-05 |
| 2014-08-06 |
| 2014-08-07 |
| 2014-08-07 |
| 2014-08-08 |
| 2014-08-09 |
| 2014-08-10 |
| 2014-08-10 |
| 2014-08-10 |
| 2014-08-11 |
| 2014-08-12 |
| 2014-08-13 |
| 2014-08-13 |
| 2014-08-13 |
| 2014-08-14 |
| 2014-08-14 |
| 2014-08-15 |
| 2014-08-16 |
| 2014-08-17 |
| 2014-08-17 |
| 2014-08-18 |
| 2014-08-18 |
| 2014-08-18 |
| 2014-08-19 |
| 2014-08-19 |
| 2014-08-20 |
| 2014-08-21 |
| 2014-08-21 |
| 2014-08-21 |
| 2014-08-22 |
| 2014-08-23 |
| 2014-08-24 |
| 2014-08-25 |
| 2014-08-25 |
| 2014-08-26 |
| 2014-08-26 |
| 2014-08-27 |
| 2014-08-28 |
| 2014-08-29 |
| 2014-08-29 |
| 2014-08-30 |
| 2014-08-31 |
| 2014-08-31 |
+------------+
50 rows in set (0.00 sec)
答案 2 :(得分:-1)
也许这样的事情会疯狂吗?
SELECT * FROM
(SELECT * FROM
(SELECT * FROM table1
WHERE `submit` = '2014-08-01'
LIMIT 48
UNION SELECT * FROM table1
WHERE `submit` = '2014-08-02'
LIMIT 48
UNION SELECT * FROM table1
WHERE `submit` = '2014-08-03'
LIMIT 48
UNION SELECT * FROM table1
WHERE `submit` = '2014-08-04'
LIMIT 48
etc...
)
UNION SELECT * FROM Table1
WHERE `submit` >= '2014-08-01' AND `submit` <= '2014-08-31'
)
order by `submit`
LIMIT 1500