【问题标题】:Process database data to new table将数据库数据处理到新表
【发布时间】:2015-12-27 05:55:55
【问题描述】:

我对编程很陌生,但我正在编写一个小软件来收集、存储和处理数据。

我有数据显示人们通勤所花费的时间,如图 A 所示(这是一个 SQL CE 数据库(精简版,不允许旋转),我正在使用 C# 和 WPF 进行编程)。我希望能够将表 A 中的数据转换为表 B 中的表格,其中多个条目按日期排序为单行,将每个人在相应行日期上花费的时间分配给他的列,并将总通勤时间相加结束。

我真的被困在这里想知道如何做到这一点。 我已经让应用程序收集和存储这些数据,如表 A 中,我想生成表 B:

【问题讨论】:

  • 你们有单独的员工桌吗?
  • 了解旋转。
  • @DevT 是的,我有一张单独的桌子供员工使用
  • @philipxy 我正在使用不允许旋转的 SQL Compact Edition

标签: c# sql wpf database sql-server-ce


【解决方案1】:

从您的问题中不清楚您是尝试在内存中(即在程序中)还是在 SQL 中创建表。当您要求“将数据...转换为表单”时,我了解到您正在尝试使用新表单创建 SQL 表。

您的要求的问题是您想要创建一个包含每个人的列的行(记录)。为此,您必须获取每一行,检查该人的列是否已经存在,如果不存在,则创建该列(使用 ALTER 命令)。虽然这是可能的,但这不是使用 SQL 表的正常方式。

正常的做法是让表A保持原样,按照“staff”(SELECT * FROM tableA ORDER BY date, Staff)排序读取它,并据此计算结果。注意 - 您应该在“员工”列上定义一个索引。这样做不需要改变表格格式,但需要编写程序来生成“报告”。

【讨论】:

  • 我想在内存中创建表。 (我在数据库中有一张员工表)
  • @SilverSurfer 为什么要这种表格格式?如果它不是在所有其他查询子表达式之后输出给人类,那么这不太可能是一个好主意。这个答案解释了生成它的一些困难,而且它通常不会完成,但也许它并没有清楚地表明(除了展示给一个人)它只是让你的生活更加复杂。
【解决方案2】:

似乎MySQL View 将无法使用准备好的语句或存储过程。

构建查询字符串方法

您可以使用两个查询,其中一个提供员工列表,第二个提供动态生成的表 B。

获取您的员工名单:

SELECT staff FROM A GROUP BY staff

制作字符串

然后循环遍历每个员工并为每个员工生成这个字符串:

(SELECT sum(A2.time) FROM A as A2 WHERE date=A1.date AND staff="<staff>") AS <staff>,

查询

然后生成了这个字符串,在这个查询中使用它:

SELECT A1.date,
    <insert-generated-query-string-of-staff>
    sum(time)
FROM A as A1 GROUP BY date;

这可能看起来像这样生成的:

SELECT A1.date,
    (SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="John") AS John,
    (SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="Jeff") AS Jeff,
    (SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="James") AS James,
    SUM(A1.time)
FROM A as A1 GROUP BY date;

准备好的语句方法

除了您通过 MySQL 而不是您的程序构建查询字符串之外,与之前的方法类似。每次要生成表数据时都需要执行这些操作。

SELECT GROUP_CONCAT( DISTINCT CONCAT(
    "(SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff=\"",
    staff,
    "\") AS ", 
    staff
) ) INTO @staff from A;

SET @table_b = CONCAT(
    'SELECT A1.date, ',
    @staff, 
    ', SUM(A1.time) FROM A as A1 GROUP BY date'
);

PREPARE tableB from @table_b;
EXECUTE tableB;

存储过程方法

我遇到了一些其他想法,主要是通过准备好的语句示例 和/或存储过程,并提出了这个过程。

我认为这个更好,因为您不必重新创建查询 准备好的语句。

制作程序:

DROP PROCEDURE generate_table_B;
DELIMITER //

CREATE PROCEDURE generate_table_B()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE staff_name VARCHAR(50) DEFAULT NULL;
    DECLARE staff_list CURSOR FOR SELECT staff FROM A GROUP BY staff;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN staff_list;
    SET @staff_stmts = '';
    get_id: LOOP
        FETCH staff_list INTO staff_name;
        IF done = 1 THEN
            LEAVE get_id;
        END IF;
        SET @staff_stmts = CONCAT(@staff_stmts, ' (SELECT SUM(A2.time) FROM A as A2 WHERE date=A1.date AND staff="', staff_name,'") AS ', staff_name,',');
    END LOOP get_id;
    CLOSE staff_list;
    SET @table = CONCAT('SELECT A1.date, ', @staff_stmts, ' SUM(A1.time) FROM A as A1 GROUP BY date');
    -- verifying the @table string generated
    -- select @table;
    PREPARE stmt FROM @table;
    -- run @table
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END //

DELIMITER ;

在程序/脚本中调用的语句:

call generate_table_B();

别名

这些是在列名、计算、查询或表之后指定的。 在其中之一之后使用AS 是可选的。

原因是嵌套查询。在这种情况下,如果我们不使用 内部查询的别名将根据其查询与数据进行比较 从外部查询。根据情况,这可能是所需的 结果。但是,下面的查询表明这不是我们想要的。

> SELECT date,
    ->     (SELECT SUM(time) FROM A WHERE date=date AND staff="John") AS John,
    ->     (SELECT SUM(time) FROM A WHERE date=date AND staff="Jeff") AS Jeff,
    ->     (SELECT SUM(time) FROM A WHERE date=date AND staff="James") AS James,
    ->     SUM(time)
    -> FROM A GROUP BY date;
+------+------+------+-------+-----------+
| date | John | Jeff | James | SUM(time) |
+------+------+------+-------+-----------+
|    1 |    9 |    8 |     4 |        10 |
|    2 |    9 |    8 |     4 |        11 |
+------+------+------+-------+-----------+
2 rows in set (0.01 sec)

现在您可能会注意到SUM(time) 列。这有资格作为 计算,所以我们可以为这个列设置一个别名,这样使用起来更友好 选择它时。像这样:

>  SELECT date,
    ->      (SELECT SUM(time) FROM A WHERE date=date AND staff="John") AS John,
    ->      (SELECT SUM(time) FROM A WHERE date=date AND staff="Jeff") AS Jeff,
    ->      (SELECT SUM(time) FROM A WHERE date=date AND staff="James") AS James,
    ->      SUM(time) SummedTime
    ->  FROM A GROUP BY date;
+------+------+------+-------+------------+
| date | John | Jeff | James | SummedTime |
+------+------+------+-------+------------+
|    1 |    9 |    8 |     4 |         10 |
|    2 |    9 |    8 |     4 |         11 |
+------+------+------+-------+------------+
2 rows in set (0.01 sec)

所有 3 种方法的输出:

+------+-------+------+------+--------------+
| date | James | jeff | john | SUM(A1.time) |
+------+-------+------+------+--------------+
|    1 |     2 |    3 |    5 |           10 |
|    2 |     2 |    5 |    4 |           11 |
+------+-------+------+------+--------------+
2 rows in set (0.00 sec)

MySQL 表和数据:

> show create table A\G
*************************** 1. row ***************************
       Table: A
Create Table: CREATE TABLE `A` (
  `date` int(11) DEFAULT NULL,
  `staff` varchar(50) DEFAULT NULL,
  `tp` varchar(50) DEFAULT NULL,
  `time` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

> SELECT * FROM A;
+------+-------+-------+------+
| date | staff | tp    | time |
+------+-------+-------+------+
|    1 | john  | bus   |    3 |
|    1 | jeff  | car   |    3 |
|    1 | James | Train |    2 |
|    2 | Jeff  | bus   |    5 |
|    2 | john  | car   |    4 |
|    2 | james | train |    2 |
|    1 | john  | train |    2 |
+------+-------+-------+------+
7 rows in set (0.00 sec)

来源:

【讨论】:

  • 请解释如何生成 A1 和 A2,我想使用构建查询字符串方法。我正在访问一个 sqlce 数据库,你能告诉我如何构建这段代码吗?是否在一个查询中?
  • 我花了一段时间才解释我为什么使用别名。最初我认为它们可能没有必要,然后我尝试了查询(你会看到更新的答案)并意识到它确实是必要的。
  • 非常感谢@qumonio,现在我明白了代码的作用,但我有点进退两难,我想获得一个循环/代码,它可以为每个独特的成员动态生成查询根据数据库内容显示的批处理查询。这是因为用户在数据库中添加了人员和时间,所以我希望能够动态生成代码并将其作为查询发送。新年快乐。
  • 好吧,如果您在 Windows 上,也许计划任务可以帮助*nix 系统或 cronjob?对不起,我刚刚意识到您没有使用 MySQL。我试图搜索 SQL CE 是否具有事件创建能力,但我不确定我发现了什么。新年快乐。
猜你喜欢
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 2012-01-24
  • 2020-04-28
  • 2017-12-04
  • 2018-06-01
相关资源
最近更新 更多