2012-07-24 61 views
2

我有一個存儲在MySQL數據庫中的清單記錄的集合。模式如下:獲得排序結果集中的行的順序

CREATE TABLE `manifests` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `carrier_id` INT(10) UNSIGNED NOT NULL COMMENT 'The carrier for which this manifest is being made', 
    `opened` DATETIME NOT NULL COMMENT 'Time the manifest was created', 
    `closed` DATETIME NULL DEFAULT NULL COMMENT 'Time the manifest was picked up and closed', 
    PRIMARY KEY (`id`), 
    INDEX `manifests_to_carriers_id` (`carrier_id`), 
    CONSTRAINT `manifests_to_carriers_id` FOREIGN KEY (`carrier_id`) REFERENCES `carriers` (`id`) 
) 
COMMENT='List of manifests that have been created by the system' 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

在白天可能會有幾個清單關閉和分派。我可以按照他們發出的順序輕鬆地獲得某一天的所有清單。例如,我可以像這樣獲得今天派發的所有清單。

select * 
from manifests 
where date(closed) = date(now()) 
order by closed 

這將產生的數據是這樣的:

"id" "carrier_id" "opened"    "closed" 
"4" "1"   "2012-07-24 11:10:06" "2012-07-24 11:10:32" 
"5" "1"   "2012-07-24 11:10:40" "2012-07-24 11:11:08" 
"6" "1"   "2012-07-24 11:11:17" "2012-07-24 11:11:59" 

的載體需要包含在我們向他們發送以及數據的序列號。在特定日期發送的第一個應該是1,第二個2等等。在這種情況下,記錄4需要1的序列號,記錄5需要2的數目,記錄6需要3的序列號等等。

當我拉一個清單發送我只是ID選擇它

select * from manifests where id = 5 

是否有可能獲得MySQL計算上面記錄的序數,它包括在結果呢?基本上我認爲我需要的是在更早的時間創建記錄的數量,然後記錄感興趣的記錄,但是這些記錄也是在同一天創建的。有沒有一個可以做到這一點的聚合函數,或者有什麼其他的技巧可以用來實現MySQL的這個?

回答

4
SET @var_record = 0; 

SELECT *, (@var_record := @var_record + 1) AS ordinality 
FROM manifests 
WHERE DATE(closed) = DATE(NOW()) 
ORDER BY closed; 

這是你在找什麼?

編輯:新查詢:

SELECT a.*, SUM(IF(b.id IS NOT NULL, 1, 0)) AS ordinality 
FROM manifests a 
     LEFT JOIN manifests b 
      ON (DATE(a.closed) = DATE(b.closed) AND a.closed > b.closed) 
GROUP BY a.id; 

性能明智的這個查詢將是更快,更有效,因爲相比於在內部創建一個在內存中的臨時表中的子查詢方法。

要進一步優化上述查詢,您可以創建多個列closed_date DATE並在該字段上創建索引並在連接中使用此列。

你也可以嘗試與EXPLAIN表綜合指數EXTENDEX看到Optimizing Queries with EXPLAIN

如果可能的話則是最好的性能創建表覆蓋索引:

ALTER TABLE manifests ADD KEY ix1(closed_date, id, ... /*all columns used in select*/) 
+0

這就是我即將發佈的內容;我可以提出一個參考:'[MySQL記錄集中行號的巧妙技巧](http://ronaldbradford.com/blog/a-need-trick-for-a-row-number-in-a-mysql -recordset-2008-09-13 /)「。 – 2012-07-24 11:41:44

+0

當你一次取一組行時,這是一個很好的訣竅,我必須記住它,所以+1。但是,如果您選擇一個單獨的記錄,它會將其排列爲1,這實際上並不是我想要的。我需要知道,如果這是當天的第三次派遣,例如,或者第一次或第17次,而不選擇某一天的所有清單。 – GordonM 2012-07-24 11:46:40

+1

你可以嘗試新的查詢並測試你的性能。 – Omesh 2012-07-24 12:02:54

1

我沒搞出事這是有效的,但我認爲它不是最優的,所以如果有更好的方法,我仍然在尋找它。

SELECT *, (
    SELECT COUNT(closed) 
    FROM manifests AS b 
    WHERE DATE(b.closed) = DATE(a.closed) 
    AND b.closed <= a.closed) AS ordinality 
FROM manifests AS a 
WHERE a.id=5