获取字段首次更改为当前值的日期
用语言来说这是一件相当尴尬的事情,但我想要当该项目第一次切换到关税/客户时的行。 如果商品切换客户,则应返回切换日期,无论关税差异如何。如果某一商品切换项目,则返回日期不得更改,除非新项目的费率与旧项目不同。
不太确定如何使其更清楚,但我愿意接受建议。
我的查询如下所示:
SET @id = 1;
SELECT DISTINCT
ip.ItemID,
ip.ProjectID,
p.TariffID,
p.CustomerID,
cs.Date
FROM item_project ip
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
LEFT JOIN project p
ON ip.ProjectID = p.ProjectID
LEFT JOIN (
SELECT
ip.ItemID,
ip.Date
FROM item_project ip
LEFT JOIN item_project ip1
ON ip.ProjectID = ip1.ProjectID
AND ip.Date > ip1.Date
LEFT JOIN project p
ON ip.ProjectID = p.ProjectID
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
AND p.CustomerID = (
SELECT p.CustomerID
FROM project p
LEFT JOIN item_project ip
ON p.ProjectID = ip.ProjectID
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
)
AND p.TariffID = (
SELECT p.TariffID
FROM project p
LEFT JOIN item_project ip
ON p.ProjectID = ip.ProjectID
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
)
) AS cs
ON ip.ItemID = cs.ItemID
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
这给了我
"ItemID","ProjectID","TariffID","CustomerID","Date"
"1","2","1","1","2010-11-10 00:00:00"
哪个是错误的日期
SET @id=2
给了我:
"2","2","1","1",NULL
这是正确的,除了
SET @id=3
给出的 日期我:
"3","2","1","1",NULL
除了日期之外,这也是正确的。
这是数据库
CREATE TABLE IF NOT EXISTS `item_project` (
`ID` int(10) unsigned NOT NULL auto_increment,
`ItemID` varchar(10) NOT NULL,
`ProjectID` int(10) unsigned NOT NULL,
`Date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO `item_project` (`ID`, `ItemID`, `ProjectID`, `Date`) VALUES
(1, '1', 1, '2010-11-05 00:00:00'),
(2, '1', 2, '2010-11-10 00:00:00'),
(3, '1', 3, '2010-11-20 00:00:00'),
(4, '2', 2, '2010-11-21 00:00:00'),
(5, '3', 4, '2010-11-21 00:00:00'),
(6, '3', 2, '2010-11-22 00:00:00'),
(7, '1', 2, '2010-11-23 00:00:00'),
CREATE TABLE IF NOT EXISTS `project` (
`ProjectID` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(45) NOT NULL,
`TariffID` varchar(45) NOT NULL,
`CustomerID` varchar(45) NOT NULL,
PRIMARY KEY (`ProjectID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `project` (`ProjectID`, `Name`, `TariffID`, `CustomerID`) VALUES
(1, 'Test', '2', '1'),
(2, 'Another test', '1', '1'),
(3, 'Project1', '1', '1'),
(4, 'Main project', '2', '2');
CREATE TABLE IF NOT EXISTS `tariff` (
`TariffID` int(10) unsigned NOT NULL auto_increment,
`Tariff` varchar(45) NOT NULL,
PRIMARY KEY (`TariffID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `tariff` (`TariffID`, `Tariff`) VALUES
(1, 'Tariff 1'),
(2, 'Tariff 2');
编辑:项目可以返回到旧的关税或客户。在这种情况下,显示的日期应该是发生这种情况的日期。
It's a fairly awkward thing to put into words, but I want the row when the item first switched to a tariff/customer.
If an item switches customer, then the date of the switch should be returned, regardless of the difference in tariff. If an item switches projects, the date returned must not change, unless the tariff of the new project is not the same as the old one.
Not quite sure how I can make it clearer, but I'm open to suggestions.
My query looks like this:
SET @id = 1;
SELECT DISTINCT
ip.ItemID,
ip.ProjectID,
p.TariffID,
p.CustomerID,
cs.Date
FROM item_project ip
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
LEFT JOIN project p
ON ip.ProjectID = p.ProjectID
LEFT JOIN (
SELECT
ip.ItemID,
ip.Date
FROM item_project ip
LEFT JOIN item_project ip1
ON ip.ProjectID = ip1.ProjectID
AND ip.Date > ip1.Date
LEFT JOIN project p
ON ip.ProjectID = p.ProjectID
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
AND p.CustomerID = (
SELECT p.CustomerID
FROM project p
LEFT JOIN item_project ip
ON p.ProjectID = ip.ProjectID
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
)
AND p.TariffID = (
SELECT p.TariffID
FROM project p
LEFT JOIN item_project ip
ON p.ProjectID = ip.ProjectID
LEFT JOIN item_project ip1
ON ip.ItemID = ip1.ItemID
AND ip.Date < ip1.Date
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
)
) AS cs
ON ip.ItemID = cs.ItemID
WHERE ip.ItemID = @id
AND ip1.ItemID IS NULL
which gives me
"ItemID","ProjectID","TariffID","CustomerID","Date"
"1","2","1","1","2010-11-10 00:00:00"
which is the wrong date
SET @id=2
gives me:
"2","2","1","1",NULL
Which is correct, apart from the date
SET @id=3
gives me:
"3","2","1","1",NULL
which is also correct, apart from the date.
Here's the database
CREATE TABLE IF NOT EXISTS `item_project` (
`ID` int(10) unsigned NOT NULL auto_increment,
`ItemID` varchar(10) NOT NULL,
`ProjectID` int(10) unsigned NOT NULL,
`Date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO `item_project` (`ID`, `ItemID`, `ProjectID`, `Date`) VALUES
(1, '1', 1, '2010-11-05 00:00:00'),
(2, '1', 2, '2010-11-10 00:00:00'),
(3, '1', 3, '2010-11-20 00:00:00'),
(4, '2', 2, '2010-11-21 00:00:00'),
(5, '3', 4, '2010-11-21 00:00:00'),
(6, '3', 2, '2010-11-22 00:00:00'),
(7, '1', 2, '2010-11-23 00:00:00'),
CREATE TABLE IF NOT EXISTS `project` (
`ProjectID` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(45) NOT NULL,
`TariffID` varchar(45) NOT NULL,
`CustomerID` varchar(45) NOT NULL,
PRIMARY KEY (`ProjectID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `project` (`ProjectID`, `Name`, `TariffID`, `CustomerID`) VALUES
(1, 'Test', '2', '1'),
(2, 'Another test', '1', '1'),
(3, 'Project1', '1', '1'),
(4, 'Main project', '2', '2');
CREATE TABLE IF NOT EXISTS `tariff` (
`TariffID` int(10) unsigned NOT NULL auto_increment,
`Tariff` varchar(45) NOT NULL,
PRIMARY KEY (`TariffID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
INSERT INTO `tariff` (`TariffID`, `Tariff`) VALUES
(1, 'Tariff 1'),
(2, 'Tariff 2');
Edit: An item can go back to an old tariff or customer. In this case, the date shown should be the date when this happened.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有趣的情况。这是我想出的
当然,您可以根据需要插入一些
WHERE ItemID = @id
。内部查询越多越好。无论如何,它的结果是
,它似乎适用于现有的数据集。让我知道您是否可以提供它不起作用的测试数据。
Interesting situation. Here's what I came up with
Of course, you can insert in a few
WHERE ItemID = @id
as you see fit. The more there are on the inner queries, the better.At any rate, it results in
So, it appears to work with the existing dataset. Lemme know if you can provide test data which it doesn't work against.
我之前的答案似乎也适用于新数据集,但我想我理解您所看到的问题。新提出的解决方案:
<代码>
我认为它提供了您正在寻找的结果。
它更加健壮,因为内部子查询之一
i_date_pair_info
显式地将每个日期与所有后续更改(如果有)配对。然后分组消除除了最快的更改之外的所有更改。My previous answer appeared to work with the new dataset too, but I think I understand the problem you're seeing. New proposed solution:
I think it provides the result you're looking for.
It's more robust in that one of the inner subqueries,
i_date_pair_info
, explicitly pairs each date with all subsequent changes, if there is one. The grouping then eliminates all but the soonest change.