2017-06-02 50 views
1

大家好我正在嘗試創建正在運行的待處理值,就像運行總計一樣,因爲我非常接近,但是我無法做到。它產生了一些錯誤的輸出如何在sqlite中計算正在運行的待處理值

這裏是sqlite導出代碼來創建表和數據。

BEGIN TRANSACTION; 
CREATE TABLE "tab_in" (
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT, 
    "type" TEXT NOT NULL, "grams" INTEGER NOT NULL 
); 
INSERT INTO `tab_in` VALUES (1,'type1',1000); 
INSERT INTO `tab_in` VALUES (2,'type2',2000); 
CREATE TABLE "sub_" (
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT, 
    "gram1" REAL, "gram2" REAL, 
    "gram3" REAL, 
    "_date" TEXT, 
    "id_sub" INTEGER, 
    "record_count" INTEGER, 
    FOREIGN KEY(id_sub) REFERENCES sub(id) 
); 
INSERT INTO `sub_` VALUES (5,10.0,NULL,NULL,'2017-06-01 00:00:00.000',2,2); 
INSERT INTO `sub_` VALUES (7,1.45,NULL,NULL,'2017-06-01 00:00:00.000',1,3); 
INSERT INTO `sub_` VALUES (8,12.6,NULL,NULL,'2017-06-01 00:00:00.000',1,4); 
INSERT INTO `sub_` VALUES (9,NULL,13.3,NULL,'2017-06-02 00:00:00.000',2,5); 
INSERT INTO `sub_` VALUES (10,NULL,NULL,20.46,'2017-06-02 00:00:00.000',2,6); 
INSERT INTO `sub_` VALUES (11,6.23,NULL,NULL,'2017-06-02 00:00:00.000',2,7); 
CREATE TABLE "sub" (
    id INTEGER PRIMARY KEY ASC AUTOINCREMENT, 
    "_date" TEXT NOT NULL, 
    "gram" REAL NOT NULL, 
    "id_tab_in" INTEGER NOT NULL, 
    "record_count" INTEGER, 
    FOREIGN KEY(id_tab_in) REFERENCES tab_in(id) 
); 
INSERT INTO `sub` VALUES (1,'2017-05-30 00:00:00.000',14.05,1,1); 
INSERT INTO `sub` VALUES (2,'2017-05-30 00:00:00.000',50.0,2,2); 
COMMIT; 

以下是我一直在處理但無法使其工作的查詢。此查詢的

SELECT DISTINCT 
    "sub_"."_date" as "sub_._date", 
    "sub_"."gram1" as "sub_.gram1", 
    "sub_"."gram2" as "sub_.gram2", 
    "sub_"."gram3" as "sub_.gram3", 
    ( 
    (SELECT sub.gram FROM sub WHERE sub.id=sub_.id_sub) - 
    (
     SELECT ifnull(TOTAL(s.gram1), 0) + 
       ifnull(TOTAL(s.gram2), 0) + 
       ifnull(TOTAL(s.gram3), 0) 
     FROM sub_ s 
     WHERE (s.id_sub=sub_.id_sub) 
      AND (s.record_count <= sub_.record_count) 
    ) 
    ) AS 'sub_.pending', 
    "sub_".id, 
    "sub_"."id_sub" as "sub_.id_sub" 
FROM "sub_" 
LEFT OUTER JOIN "sub" ON "sub_"."id_sub"="sub".id 
WHERE "sub_"."id_sub"=1; 

輸出是(對於sub.id = 1值sub.gram是14.05)我做的基本上就是在這裏,要計算待定值我從sub.gram使用sub_.gram1sub_.gram2sub_.gram3總減去。

sub_._date     sub_.gram1 sub_.gram2 sub_.gram3 sub_.pending   id sub_.id_sub 
2017-06-01 00:00:00.000  1.45   (null)  (null)  12.600000000000001  7 1 
2017-06-01 00:00:00.000  12.6   (null)  (null)  1.7763568394002505e-15 8 1 

所需的輸出爲sub_.pending

sub_.pending 
12.6 
0 

請幫我做它的工作。

+1

術語「運行未決」是未知的,我能不能在散文你想達到什麼樣的解釋,你能不能給預期的輸出,你能解釋一下的輸出你。?查詢不能滿足你嗎?否則第一個問題很好的mcve,我的恭維。 – Yunnosch

+0

對於ID 1,我得到了sub.gram = 14.05,sub_.gram1 + 2 + 3 = 1 4.05。 Diff = 0.對於ID 2,我得到了sub.gram = 50,sub_.gram1 + 2 + 3 = 49.99。 Diff = 0.01。這與您的預期結果不符。那麼什麼是*你的*公式來加起來的子克呢? –

+0

什麼是'record_count'列?乍看之下他們似乎沒有多少意義。 –

回答

0

好的,我現在明白了。您查詢是正確的,但您不必要地查詢sub兩次。

你的問題是你的數據類型。您將值存儲爲REAL。這是一個近似的數據類型。所以你認爲你正在存儲12.6,但它被存儲爲12.600000000000001例如。這是我們在數據庫中通常不會做的事情。我們將始終存儲確切的值。然而,SQLite考慮到這一點非常差,因爲它甚至不提供十進制數的確切類型。

所以在SQLite中,你最好的選擇似乎是四捨五入。假設你知道你的價值纔有效達到你最好ROUND(value,2)小數點後兩位:

UPDATE:圓形值可能會是個REAL再次:-(最後的結果是正確的,只是不精確所以格式化。兩位小數輸出使用printf

select 
    sub_.*, 
    printf('%.2f', 
    sub.gram - 
    (
     select 
     coalesce(sum(s.gram1), 0) + 
     coalesce(sum(s.gram2), 0) + 
     coalesce(sum(s.gram3), 0) 
     from sub_ s 
     where s.id_sub = sub_.id_sub 
     and s.record_count <= sub_.record_count 
    ) 
) as pending 
from sub_ 
join sub on sub.id = sub_.id_sub 
order by sub_.id_sub, sub_.record_count; 
+0

非常感謝你的幫助,你可以請換行「其中s.id_sub = sub_id_sub的」 to「s.id_sub = sub_.id_sub」這樣的人誰也可能會發現這很有可能有正確的答案,爲什麼合併,而不是IFNULL將它有什麼區別? – user8104189

+0

啊,一個缺點。謝謝。不,「COALESCE」沒有任何區別。這只是標準的SQL函數,而'IFNULL'則是合適的。我更喜歡標準功能。 –

相關問題