将数据库数据处理到新表

时间:2015-12-27 05:55:56

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

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

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

我确实陷入困境,想知道如何做到这一点。 我已经得到了应用程序来收集和存储这些数据,如表A所示,我想生成表B:

enter image description here

2 个答案:

答案 0 :(得分:1)

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

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

正常的方法是将表A原样保留,并按“staff”(SELECT * FROM tableA ORDER BY date,Staff)排序读取并相应地计算结果。注意 - 您应该在“Staff”列中定义索引。这样做不需要改变表格格式,但需要编写程序来生成“报告”。

答案 1 :(得分:0)

似乎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表&amp;数据:

> 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)

来源: