我需要帮助计算 sql 连续出现的字符(使用 firebird 服务器)

I need help counting char occurencies in a row with sql (using firebird server)

我有一个 table,其中有这些字段:

id(主键,自增)
车牌号
汽车模型
车库编号

每行的每一天都有 31 个字段。

在这些字段中,我有 1 个或 2 个字符的字符代表该日期的汽车状态。我需要查询以获取当天每种可能性的数量,任何一天的字段都可以有值:D, I, R, TA, RZ, BVLR.

我需要在每一行中计算该行中每个值的数量。 比如有多少 I ,有多少 D 等等。这适用于 table 中的每一行。 这里有什么最好的方法?也可能有比每天在数据库 table 中有字段更好的方法,因为它显然有超过 30 个字段。

有更好的方法。您应该构建数据,以便您有另一个 table,其中的行如下:

  • CarId
  • 日期
  • 状态

那么您的查询将是:

select status, count(*)
from CarStatuses
where date >= @month_start and date < month_end
group by status;

对于您的数据模型,这更难处理。你可以这样做:

select status, count(*)
from ((select status_01 as status
       from t
      ) union all
      (select status_02
       from t
      ) union all
      . . .
      (select status_31
       from t
      )
     ) s
group by status;

您似乎必须从大多数有关关系数据库和SQL 设计的基础教程开始。 "Martin Gruber - Understanding SQL" 等一些经典作品可能会有所帮助。或者其他人。 ATM 你错过了基础知识。

一些提示。

  1. 您为用户打印或从用户那里收到的文档不代表您的内部数据结构。它们 created/parsed 正是为了实现机器对人机界面的目的。在你的程序中应该构造数据以便于 storing/processing.

  2. 您必须为状态添加 "dictionary table"。

ID/缩写/人类可读的描述

您可能有一个 "business rule",您可以从 "R" 状态转换到 "D" 状态或 "BV" 状态,但不能转换到任何其他状态。换句话说,您最好起草可能的状态转换 "directed graph"。您可以将其保存在该字典的额外列中 table 或一个更专门的助手 table 中。可能状态字典的转换字典。

  1. 您的空白纸在同一行中结合了总数和每天的详细信息。这对人来说很容易看,但对计算机来说在某种意义上违反了单一职责原则。行应负责主要记录或导出的总计计算。您最好有两个 tables - 一个用于主要的日常记录,另一个用于每月总计。

  2. 奖励点是当您更改主要数据中的值时 table 您可以要求服务器自动重新计算相应的月份总计。了解 SQL triggers.

  3. 此外,您的触发器可能会检查新状态是否从前一天的状态正确过渡,如 "business rules" 中所述。他们可能还必须检查一天之间是否有间隔。如果有 "march 03" 的记录并且插入了 "march 05" 的新记录,那么 "march 04" 的记录应该存在,否则服务器将禁止添加这样的行。好吧,也许不是,这取决于您的业务流程。一般的想法是服务器应该拒绝存储任何无效的数据并且服务器可以知道它。

  4. 你每个日期和每个月 tables 应该有适当的 UNIQUE CONSTRAINTs 禁止输入重复行。这也意味着前者应该有 DATE 类型的列,后者应该有月份和年份 INTEGER 类型的列,或者有 DATE 类型的列,其中日期部分始终为“1”——你会想要一个 CHECK CONSTRAINT 为它。

  5. 如果你的公司有一些汽车登记处(而且可能有,这些车看起来不像是随机的一次性顾客开车经过的)你必须引入一本字典table的汽车。整数 ID (PK)、车牌、发动机出厂编号、货车出厂编号、颜色和其他任何内容。

  6. 每月总计 table 每个状态的列不会很多。相反,每个状态都有一个特殊的行!结构可能是这样的:月/年/注册表中的汽车 ID/字典中的状态 ID/计数。所有列都是整数类型(有些可能是 SmallInt 或 BigInt,但这是细微差别)。所有列一起(没有计数列)应该构成 UNIQUE CONSTRAINT 或更好的 "compound" Primary Key。在总计 table 中添加一个特殊的专用 PK 列对我来说似乎是多余的。

  7. 因此,您的每日和每月 tables 不会有状态和汽车 ID 的文字(文本和即时)数据。相反,他们将拥有引用相应汽车字典和状态字典 table 中正确记录的整数 ID。您将编码为 FOREIGN KEY.

记住经验法则:add/delete 一行到任何 table 很容易,但很难 add/delete 一列。

像你这样的设计,以栏目为导向,如果明年老板再推出一些状态会怎么样?你将不得不重新设计table,程序在很多方面等等。

使用面向行的设计,您只需在状态字典中添加一行,并可能向转换规则字典中添加几行,其余的无需任何更改即可工作。 这样你就不会