如何计算sqlite中的运行挂起值

时间:2017-06-02 17:44:42

标签: sql database 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 个答案:

答案 0 :(得分: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;