2017-06-02 53 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'则是合适的。我更喜欢标准功能。 –

相关问题