Raf*_*lks 1 mysql select date-range sequence
我的目标是在列中返回具有相同值的开始和结束日期。这是我的桌子。已标记 (*) 以让您了解我希望如何为 A 和 B 列的每个相似序列值获取“EndDate”
ID | DayDate | A | B
-----------------------------------------------
1 | 2010/07/1 | 200 | 300
2 | 2010/07/2 | 200 | 300 *
3 | 2010/07/3 | 150 | 250
4 | 2010/07/4 | 150 | 250 *
8 | 2010/07/5 | 150 | 350 *
9 | 2010/07/6 | 200 | 300
10 | 2010/07/7 | 200 | 300 *
11 | 2010/07/8 | 100 | 200
12 | 2010/07/9 | 100 | 200 *
Run Code Online (Sandbox Code Playgroud)
我想从上表中得到以下结果表
| DayDate |EndDate | A | B
-----------------------------------------------
| 2010/07/1 |2010/07/2 | 200 | 300
| 2010/07/3 |2010/07/4 | 150 | 250
| 2010/07/5 |2010/07/5 | 150 | 350
| 2010/07/6 |2010/07/7 | 200 | 300
| 2010/07/8 |2010/07/9 | 100 | 200
Run Code Online (Sandbox Code Playgroud)
更新:
谢谢迈克,您的方法似乎在您将以下行视为错误的角度来看有效。
8 | 2010/07/5 | 150 | 350 *
Run Code Online (Sandbox Code Playgroud)
然而,这并不是一个错误。我面临的这类数据的挑战就像记录市场价格随日期变化的场景。mycase 中的真正问题是如果 A 和 B 在所有这些行中都匹配,则选择具有开始日期和结束日期的所有行。还可以选择与先前选择的行相邻的行,依此类推,表中不会遗漏任何数据。
我可以解释一个真实世界的场景。如我的问题中所述,带有 A 室和 B 室的酒店将每天的房价输入到表中。现在,酒店需要获得一份报告,以使用开始和结束日期以更短的方式显示价格日历,而不是列出所有输入的日期。比如2010/07/01到2010/07/02,A的价格是200,B的价格是300。这个价格从3号到4号,5号才有不同的价格,只有B房的那一天价格更改为 350。所以这被视为单日差异,这就是为什么开始和结束日期相同。
我希望这可以解释问题的情况。另请注意,这家酒店可能会在特定时间段内关闭,可以说这是我第一个问题的另一个问题。问题是如果没有在特定日期输入价格会怎样,例如在星期天酒店不出售这两个房间,所以他们没有输入价格,这意味着表中将不存在该行。
创建相关表可以让您更自由地查询和提取相关信息。以下是一些您可能会觉得有用的链接:
您可以从这些教程开始:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
http://net.tutsplus.com/tutorials/databases/sql-for-beginners/
这里还有一些关于 stackoverflow 的问题可能有用:
用简单的英语规范化
数据库规范化到底是做什么的?
无论如何,找到一个可能的解决方案。以下示例使用您的酒店房间类比。
首先,创建一个表来保存有关酒店房间的信息。该表仅包含房间 ID 及其名称,但您可以在此处存储其他信息,例如房间类型(单人房、双人房、双床房)、其景观(海景、海景、城市景观、泳池景观)以及很快:
CREATE TABLE `room` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `name_UNIQUE` (`name` ASC) )
ENGINE = InnoDB;
Run Code Online (Sandbox Code Playgroud)
现在创建一个表格来保存不断变化的房价。该表room通过room_id列链接到该表。外键约束防止将记录插入到rate表中,这些记录指的是不存在的房间:
CREATE TABLE `rate` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`room_id` INT UNSIGNED NOT NULL,
`date` DATE NOT NULL,
`rate` DECIMAL(6,2) UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_room_rate` (`room_id` ASC),
CONSTRAINT `fk_room_rate`
FOREIGN KEY (`room_id` )
REFERENCES `room` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
Run Code Online (Sandbox Code Playgroud)
创建两个房间,并添加一些关于每个房间的每日房价信息:
INSERT INTO `room` (`id`, `name`) VALUES (1, 'A'), (2, 'B');
INSERT INTO `rate` (`id`, `room_id`, `date`, `rate`) VALUES
( 1, 1, '2010-07-01', 200),
( 2, 1, '2010-07-02', 200),
( 3, 1, '2010-07-03', 150),
( 4, 1, '2010-07-04', 150),
( 5, 1, '2010-07-05', 150),
( 6, 1, '2010-07-06', 200),
( 7, 1, '2010-07-07', 200),
( 8, 1, '2010-07-08', 100),
( 9, 1, '2010-07-09', 100),
(10, 2, '2010-07-01', 300),
(11, 2, '2010-07-02', 300),
(12, 2, '2010-07-03', 250),
(13, 2, '2010-07-04', 250),
(14, 2, '2010-07-05', 350),
(15, 2, '2010-07-06', 300),
(16, 2, '2010-07-07', 300),
(17, 2, '2010-07-08', 200),
(18, 2, '2010-07-09', 200);
Run Code Online (Sandbox Code Playgroud)
存储该信息后,带有 的简单SELECT查询JOIN将显示所有每日房价:
SELECT
room.name,
rate.date,
rate.rate
FROM room
JOIN rate
ON rate.room_id = room.id;
+------+------------+--------+
| A | 2010-07-01 | 200.00 |
| A | 2010-07-02 | 200.00 |
| A | 2010-07-03 | 150.00 |
| A | 2010-07-04 | 150.00 |
| A | 2010-07-05 | 150.00 |
| A | 2010-07-06 | 200.00 |
| A | 2010-07-07 | 200.00 |
| A | 2010-07-08 | 100.00 |
| A | 2010-07-09 | 100.00 |
| B | 2010-07-01 | 300.00 |
| B | 2010-07-02 | 300.00 |
| B | 2010-07-03 | 250.00 |
| B | 2010-07-04 | 250.00 |
| B | 2010-07-05 | 350.00 |
| B | 2010-07-06 | 300.00 |
| B | 2010-07-07 | 300.00 |
| B | 2010-07-08 | 200.00 |
| B | 2010-07-09 | 200.00 |
+------+------------+--------+
Run Code Online (Sandbox Code Playgroud)
要查找每个房价的开始和结束日期,您需要一个更复杂的查询:
SELECT
id,
room_id,
MIN(date) AS start_date,
MAX(date) AS end_date,
COUNT(*) AS days,
rate
FROM (
SELECT
id,
room_id,
date,
rate,
(
SELECT COUNT(*)
FROM rate AS b
WHERE b.rate <> a.rate
AND b.date <= a.date
AND b.room_id = a.room_id
) AS grouping
FROM rate AS a
ORDER BY a.room_id, a.date
) c
GROUP BY rate, grouping
ORDER BY room_id, MIN(date);
+----+---------+------------+------------+------+--------+
| id | room_id | start_date | end_date | days | rate |
+----+---------+------------+------------+------+--------+
| 1 | 1 | 2010-07-01 | 2010-07-02 | 2 | 200.00 |
| 3 | 1 | 2010-07-03 | 2010-07-05 | 3 | 150.00 |
| 6 | 1 | 2010-07-06 | 2010-07-07 | 2 | 200.00 |
| 8 | 1 | 2010-07-08 | 2010-07-09 | 2 | 100.00 |
| 10 | 2 | 2010-07-01 | 2010-07-02 | 2 | 300.00 |
| 12 | 2 | 2010-07-03 | 2010-07-04 | 2 | 250.00 |
| 14 | 2 | 2010-07-05 | 2010-07-05 | 1 | 350.00 |
| 15 | 2 | 2010-07-06 | 2010-07-07 | 2 | 300.00 |
| 17 | 2 | 2010-07-08 | 2010-07-09 | 2 | 200.00 |
+----+---------+------------+------------+------+--------+
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到对上述查询中使用的技术的很好解释:http :
//www.sqlteam.com/article/detecting-runs-or-streaks-in-your-data
| 归档时间: |
|
| 查看次数: |
3427 次 |
| 最近记录: |