2010-11-26 63 views
1

將字詞放入是一件相當尷尬的事情,但是當項目首次切換到關稅/客戶時,我想要該行。 如果一個項目切換客戶,那麼無論關稅有什麼不同,都應該返回交換機的日期。如果項目切換項目,則返回的日期不得更改,除非新項目的關稅與舊項目的關稅不相同。獲取字段第一次更改爲其當前值的日期

不太清楚我如何使它更清晰,但我願意提供建議。

我的查詢看起來是這樣的:

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 

瓦ICH是正確的,除了日期

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'); 

編輯:一個項目可以回到一個老關稅或客戶。在這種情況下,顯示的日期應該是發生這種情況的日期。

回答

1

我以前的答案似乎也適用於新的數據集,但我想我理解您遇到的問題。新建議的解決方案:

SELECT i_general.ItemID, ProjectID, TariffID, CustomerID, the_date 
FROM 
(
    SELECT ip.ItemID, p.ProjectID, p.TariffID, p.CustomerID 
    FROM item_project ip 
    INNER JOIN project p ON ip.ProjectID = p.ProjectID 
    INNER JOIN tariff t ON p.TariffID = t.TariffID 
    INNER JOIN (
     SELECT ip.ItemID, MAX(Date) AS max_date 
     FROM item_project ip 
     GROUP BY ip.ItemID 
    ) ip_max ON ip_max.ItemID=ip.ItemID AND ip_max.max_date=ip.Date 
) i_general 
INNER JOIN 
(
    SELECT ItemID_1 AS ItemID, IF(MAX(Next_Change_Date) IS NULL, MIN(Date_1), MAX(Next_Change_Date)) AS the_date 
    FROM 
    (
     SELECT ItemID_1, Date_1, MIN(Date_2) AS Next_Change_Date 
     FROM 
     (
      SELECT ip1.ItemID AS ItemID_1, ip1.Date AS Date_1, p1.TariffID AS TariffID_1, p1.CustomerID AS CustomerID_1 
      FROM item_project ip1 
      INNER JOIN project p1 ON ip1.ProjectID = p1.ProjectID 
     ) ipp1 
     LEFT JOIN 
     (
      SELECT ip2.ItemID AS ItemID_2, ip2.Date AS Date_2, p2.TariffID AS TariffID_2, p2.CustomerID AS CustomerID_2 
      FROM item_project ip2 
      INNER JOIN project p2 ON ip2.ProjectID = p2.ProjectID 
     ) ipp2 ON ItemID_1=ItemID_2 AND Date_1 < Date_2 AND ((TariffID_1!=TariffID_2 OR CustomerID_1!=CustomerID_2) AND Date_2 IS NOT NULL) 
     GROUP BY ItemID_1, Date_1 
    ) i_date_pair_info 
    GROUP BY ItemID 
) i_date_info ON i_date_info.ItemID = i_general.ItemID

我認爲它提供了您正在尋找的結果。

它更健壯,其中一個內部子查詢i_date_pair_info明確地將每個日期與所有後續更改(如果有的話)進行配對。然後這個分組消除了除了最快的變化之外的所有變化。

2

有趣的情況。以下是我想出了

SELECT i_general.ItemID, ProjectID, TariffID, CustomerID, the_date 
FROM 
(
    SELECT 
     ip.ItemID, 
     p.ProjectID, 
     p.TariffID, 
     p.CustomerID 
    FROM item_project ip 
    INNER JOIN project p ON ip.ProjectID = p.ProjectID 
    INNER JOIN tariff t ON p.TariffID = t.TariffID 
    INNER JOIN (
     SELECT 
      ip.ItemID, MAX(Date) AS max_date 
     FROM item_project ip 
     GROUP BY ip.ItemID 
     ) ip_max ON ip_max.ItemID=ip.ItemID AND ip_max.max_date=ip.Date 
) i_general 
INNER JOIN (
    SELECT ip1.ItemID, IF(MIN(ip2.Date) IS NULL,MIN(ip1.Date),MIN(ip2.Date)) AS the_date 
    FROM item_project ip1 
    INNER JOIN project p1 ON ip1.ProjectID = p1.ProjectID 
    LEFT JOIN item_project ip2 ON ip1.ItemID=ip2.ItemID AND ip1.Date < ip2.Date 
    LEFT JOIN project p2 ON ip2.ProjectID = p2.ProjectID AND (p2.TariffID!=p1.TariffID OR p2.CustomerID!=p1.CustomerID) 
    GROUP BY ip1.ItemID 
    ) i_date_info ON i_date_info.ItemID = i_general.ItemID 

當然,你可以在幾WHERE ItemID = @id你認爲合適的插入。內部查詢越多,效果越好。

在任何情況下,它會導致

+--------+-----------+----------+------------+---------------------+ 
| ItemID | ProjectID | TariffID | CustomerID | the_date   | 
+--------+-----------+----------+------------+---------------------+ 
| 1  |   3 | 1  | 1   | 2010-11-10 00:00:00 | 
| 2  |   2 | 1  | 1   | 2010-11-21 00:00:00 | 
| 3  |   2 | 1  | 1   | 2010-11-22 00:00:00 | 
+--------+-----------+----------+------------+---------------------+ 

因此,它似乎與現有的數據集工作。 Lemme知道你是否可以提供它不起作用的測試數據。

+1

+1這絕對適用於測試數據,但我似乎遇到了與實際數據有關的問題。當我確定一個模式時,我會添加更多的測試數據,但是這將不得不等到下週。 – 2010-11-26 15:50:23

+0

更新了問題。導致問題的數據是從一個客戶/關稅改變而來的項目,然後再返回。 – 2010-11-29 09:44:16

相關問題