【问题标题】:MariaDB: calculating with calculated columnsMariaDB:使用计算列进行计算
【发布时间】:2019-07-27 18:54:11
【问题描述】:

我对 SQL 很陌生,并尝试使用 Mariadb (10.3.15) 上的其他计算结果进行计算。 我运行了一个使用子查询的版本。 但是,关于 mysql、oracle 或 SqlServer,讨论了其他对我来说更容易理解的解决方案,但它们都不适用于 MariaDB。

我想了解 MariaDB SQL 语法是否只是有点不同,或者该功能在 MariaDB 中是否不可用。

CREATE TABLE test.testcalculation (
  ID int(11) NOT NULL AUTO_INCREMENT,
  num1 int(11) DEFAULT NULL,
  num2 int(11) DEFAULT NULL,
  num3 int(11) DEFAULT NULL,
  num4 int(11) DEFAULT NULL,
  PRIMARY KEY (ID)
)
ENGINE = INNODB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;


USE test;
INSERT INTO testcalculation(num1, num2, num3, num4) VALUES(1, 2, 3, 4);
INSERT INTO testcalculation(num1, num2, num3, num4) VALUES(5, 10, 15, 20);

这个效果很好:

SELECT
  id,
  Number1,
  Number2,
  Number3,
  Number4,
  Sum1And2,
  Sum1And2Prod3,
  (Sum1And2 + Sum1And2Prod3) AS "SumOfCalculations"
FROM (SELECT
    id,
    num1 AS Number1,
    num2 AS Number2,
    num3 AS Number3,
    num4 AS Number4,
    (num1 + num2) AS Sum1And2,
    ((num1 + num2) * num3) AS Sum1And2Prod3
  FROM test.testcalculation) t;

(顺便说一句,最后没有“t”是什么意思?)

所以我有一个解决方案,但那是把所有东西都写两次,如果我需要另一个级别的计算,可能会变得相当复杂。

这个逻辑是针对 Oracle 讨论的,不适用于 MariaDB

SELECT
  id,
  num1,
  num2,
  num3,
  num4,
  c.Sum1And2 AS Sum1And2,
  (c.Sum1And2 * num3) AS Sum1And2Prod3
  FROM test.testcalculation
  CROSS apply (SELECT (num1 + num2) AS Sum1And2) AS c;

显然 MariaDB 不知道“交叉应用”

但作为 SQL 和 MariaDB 的新手,我只是想知道我的其他选择,也许像这样更具可读性,我在互联网上找到的:

CREATE TABLE test.signups_by_month (
  id int(11) NOT NULL AUTO_INCREMENT,
  month date DEFAULT NULL,
  signups int(11) DEFAULT NULL,
  visitors int(11) DEFAULT NULL,
  PRIMARY KEY (id)
)
ENGINE = INNODB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;


INSERT INTO signups_by_month(month, signups, visitors) VALUES('2014-06-01', 133, 1910);
INSERT INTO signups_by_month(month, signups, visitors) VALUES('2014-01-07', 95, 3151);
INSERT INTO signups_by_month(month, signups, visitors) VALUES('2014-01-08', 118, 1844);

    select 
      month, 
      signups, 
      visitors, 
      p as avg, 
      low, 
      high
    from signups_by_month,
    lateral (select signups / visitors as p) probability,
    lateral (select sqrt(p * (1 - p) / visitors) as se) std_error,
    lateral (select p - 1.94 * se as low) lower_bound,
    lateral (select p + 1.94 * se as high) upper_bound;

我得到的唯一错误信息是,有一个错误:

您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,了解在 '(select signups / visitor as p) 概率附近使用的正确语法 横向(选择 sqrt(p * (1' at line 17 SQL4.sql 1 5

显然,MariaDB 在“横向”之后需要“加入”。我不确定标准 SQL 的结束位置和供应商实现的开始位置。我刚刚读到“横向”是 SQL 99,因此认为它应该以某种方式工作。用计算来计算并不是真正花哨的火箭科学。

我只是想了解那(交叉应用/横向)是否根本无法在 MariaDB 上运行,或者如果是,如何?我还尝试深入研究 CTE,但到目前为止无法运行该示例...

也许有人可以向我解释其他选项或(考虑上面的示例)“最佳”解决方案。或者只是声明除了子查询或 CTE 之外别无其他(我可以自己深入研究),因此我没有理由花更多时间交叉应用或横向应用。

【问题讨论】:

  • MariaDB 不支持横向连接。使用子查询或 CTE。
  • RDBMS 供应商之间存在很多差异。
  • 您询问的t 是一个“别名”。在这种情况下,它是您可以引用派生表的名称。 MariaDB 需要所有派生表的别名。
  • LATERALCROSS APPLY 是相当复杂的连接,不应轻易使用。看来您根本不需要它们,如果使用不当,它们会严重影响性能。
  • 请添加预期结果。您要查找的查询可能很简单,不需要LATERALCROSS APPLY

标签: sql mariadb


【解决方案1】:

一种方法是使用数据库变量

create table testcalc (
   id int(11) not null auto_increment,
   num1 int(11) default null,
   num2 int(11) default null,
   num3 int(11) default null,
   num4 int(11) default null,
   primary key(id)
);

insert into testcalc values
(default, 1, 2, 3, 4),
(default, 5, 10, 15, 20);

然后您可以通过将计算结果存储在像这样的变量语法中来获得与示例中相同的结果

@youVar := (calc) as resultName01

那么它将可用于以下计算以像这样使用

(@youVar + newCalc) as resultName02

我们可以像这样将它应用到您的示例中

select
   id,
   num1,
   num2,
   num3,
   num4,
   @1plus2 := (num1 + num2) as 1plus2,                   # create var01
   @1plus2mult3 := (@1plus2 * num3) as 1plus2mult3,      # create var02 using var01
   @sumOfCalc := (@1plus2 + @1plus2mult3) as sumOfCalc   # create var03 using var01 and var02
from testcalc;

这给了

| id | num1 | num2 | num3 | num4 | 1plus2 | 1plus2mult3 | sumOfCalc |
| 1  | 1    | 2    | 3    | 4    | 3      | 9           | 12        |
| 2  | 5    | 10   | 15   | 20   | 15     | 225         | 240       |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2015-04-15
    • 2013-09-06
    相关资源
    最近更新 更多