编写这些SQL语句的更好方法

时间:2012-07-26 19:48:53

标签: mysql sql

我想阅读数据用于报告目的。目前,我使用另一个表的计算数据填充表,并从填充的表中读取数据以进行报告。我当前的逻辑是删除旧数据,并在事务中插入新数据。

更新

要求

1)以下逻辑是每秒运行一次。请注意,其他进程也会使用相同的刷新率来更新tableB。

2)TableB用于报告目的。 TableA和TableB驻留在不同的数据库中。

3)TableB包含大约1000万行,每秒约400万行将由下面的代码更新一次。其他进程也以相同的刷新率更新tableB中的其他数据部分(6 = 10-4百万)。

我担心的是:

1)三个语句使用类似的和,以及where子句,可能会有所改进。

2)tablea中有大约1-2百万行要更新到tableB。使用显式临时表可能会变慢。

3)使用交易可能会减慢速度,但这似乎是唯一的方法。

4)更新数据可能是一个比删除和插入更好的选择(我应该选择哪一个?)

我想找到一种更好的表现方式(包括表格重新设计等)。以下是目前的方式:

下面的伪代码:

start/begin transaction here    

DELETE from tableb data that I want to insert below, e.g. delete data where Code = 'code'


INSERT INTO tableb(Code, Total)
SELECT sum(a.Code, price)
FROM tablea a
GROUP BY a.Code;

IINSERT INTO tableb(Code, Total)
SELECT sum(a.Code price)   -- use price
FROM tablea a
WHERE a.meanPrice IS NOT NULL
GROUP BY a.Code;

INSERT INTO tableb(Code, Total)
SELECT sum(a.Code, meanPrice )   -- use meanPrice
FROM tablea a
WHERE a.meanPrice IS NOT NULL
GROUP BY a.Code;


Commit transaction here

适用于MySQL,但理想情况下它应该是通用的。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

您确实需要更新表格中的值吗?它们没有标记任何ID或名称来识别它们。

以下SELECT语句返回所需的数据:

SELECT code,
       sum(price),
       sum(case when a.meanPrice is not null then price else 0 end),
       sum(case when a.meanPrice is not null then meanprice else 0 end)
FROM tablea a
GROUP BY a.Code;

如果需要将其插入临时表,则可以取消数据。但是,这种格式对我来说没有意义。你能用这种方式解释为什么要使用带有一个数字列的表吗?

答案 1 :(得分:1)

第3点是错误的。

解决方案1:创建商店程序。

解决方案2:在受影响的表上创建触发器。

解决方案3:不要每次都要求总和,第一次做总和,然后将数字保存在另一张桌子上。在这个表的每次修改中,对新表进行总结,我不会是1百万条记录,每个表只有一条。

数据透视表!

答案 2 :(得分:1)

此查询只需1步即可完成INSERT任务,但是......孩子们,如果没有实际测量实际效果,请不要在家中执行此操作:

http://sqlfiddle.com/#!2/381e2/9

INSERT INTO tableb(Total)
SELECT
  CASE
    WHEN t.v = 1
    THEN SUM( price )

    WHEN t.v = 2
    THEN SUM(
           CASE
           WHEN meanPrice IS NOT NULL THEN price
           ELSE 0
           END
         )

    WHEN t.v = 3
    THEN SUM( meanPrice )
  END AS Total

FROM tablea

INNER JOIN
  ( SELECT 1 AS v UNION ALL
    SELECT 2 AS v UNION ALL
    SELECT 3 AS v
  ) AS t

GROUP BY tablea.Code, t.v;