用于跟踪全年销售的 SQL 关系数据库

Posted

技术标签:

【中文标题】用于跟踪全年销售的 SQL 关系数据库【英文标题】:SQL relational database for tracking sales throughout a year 【发布时间】:2019-01-24 22:34:34 【问题描述】:

我是关系数据库和 mysql 的菜鸟。我的任务是创建一个可以跟踪全年销售情况的应用程序。因此,当员工进行销售时,销售金额和销售日期都会保存在数据库中。

这个数据库需要保存当天、周、月和年的当前销售额。它还需要跟踪这些销售属于哪个员工,以及该员工在特定日期的销售额。

我画了一个database diagram 并在 MySQL 中构建了表。我遇到的问题是我听说(通过在线教程等)多对多或联结表不应该有重复。

嗯,我的连接表将是我的销售表。它与进行销售的员工是多对一的,与当天的销售是多对一的。因此,employee1 一天进行了 3 次销售,我的销售表如下所示:

sale_id | sale_amount | day_id | employee_id
1         500           1        1
2         600           1        1
3         750           1        1

day_id 是当天,employee_id 是employee1。问题 1,这很糟糕吗?如果是,有什么更好的解决方案?

问题 2,确定一年中的天/周/月以跟踪所有这些数据的最佳方法是什么?手动输入每周 7 天、每年 52 周和每年 12 个月似乎过于繁琐。我进入了 5 年,然后我进入了第一年的 12 个月,第一年的 52 周,然后在添加天数之前停下来,看看是否有更好的解决方案。

对此的任何帮助将不胜感激。如果可能的话,我也想在没有任何额外的第三方软件的情况下做到这一点。

非常感谢任何帮助!

【问题讨论】:

不需要总和表。只需记录销售和员工。简单的查询可以生成针对个别天、周、月和年的结果。查看日期/时间函数。如果您将销售日期存储为敢或日期时间或时间戳类型,这些功能将允许您轻松按日期变体分解销售。 您可能需要考虑根据未来可能的报告需求为部门或部门添加列。 【参考方案1】:

将日期存储为日期时间类型,而不是包含天、周、月和年的表格。您只需要两张桌子。

员工表

DROP TABLE IF EXISTS `employees`;

CREATE TABLE IF NOT EXISTS `tablename` (
    `emp_id`        INT(11) UNSIGNED        NOT NULL    AUTO_INCREMENT                  COMMENT 'Primary Key',
    `emp_name`      VARCHAR(200)            NOT NULL    DEFAULT ''                      COMMENT 'Name of employee',
    `emp_email`     VARCHAR(200)            NOT NULL    DEFAULT ''                      COMMENT 'Email address of employee',
    `emp_password`  VARCHAR(200)            NOT NULL    DEFAULT ''                      COMMENT 'Password encoded',
    PRIMARY KEY (`emp_id`),
    UNIQUE `idx_emp_name` (`emp_name`),
    UNIQUE `idx_emp_email` (`emp_email`)
) 
    ENGINE=MyISAM 
    AUTO_INCREMENT=1 
    DEFAULT CHARSET=utf8 
    COLLATE=utf8_unicode_ci
    COMMENT 'List of Employees';

销售表

DROP TABLE IF EXISTS `sales`;

CREATE TABLE IF NOT EXISTS `tablename` (
    `sale_id`           INT(11) UNSIGNED        NOT NULL    AUTO_INCREMENT                  COMMENT 'Primary Key',
    `sale_amount`       DOUBLE                  NOT NULL    DEFAULT 0                       COMMENT 'Amount Of Sale',
    `sale_date`         DATETIME                NOT NULL    DEFAULT '0000-00-00'            COMMENT 'Date/Time of sale',
    `sale_emp_id`       INT(11)                 NOT NULL                                    COMMENT 'FK To employees',
    PRIMARY KEY (`sale_id`),
    KEY `idx_sale_date` (`sale_date`),
    KEY `idx_sale_emp_id` (`sale_emp_id`)
) 
    ENGINE=MyISAM 
    AUTO_INCREMENT=1 
    DEFAULT CHARSET=utf8 
    COLLATE=utf8_unicode_ci
    COMMENT 'List of Employees';

-- ==============================================================================================
-- TRIGGER: Update sale_date timestamp on sales
-- ==============================================================================================
DELIMITER |

DROP TRIGGER IF EXISTS `sales_CreatedTS`|

CREATE TRIGGER `sales_CreatedTS` BEFORE INSERT ON `sales`
FOR EACH ROW
BEGIN
    SET NEW.`sale_date` = CURRENT_TIMESTAMP;
END|

DELIMITER ;

从这些表格中,您可以按您需要的任何期间类型生成任何报告。

例如,您可以按员工和周生成带有小计的报告,如下所示:

SELECT
    a.`emp_name`,
    WEEK(b.`sale_date`) as `week_no`,
    SUM(b.`sale_amount`) as `total_sales_for_week`
FROM `employees` a
JOIN `sales` b
    ON a.`emp_id` = b.`sales_emp_id`
GROUP BY WEEK(b.`sale_date`),a.`emp_id` WITH ROLLUP;

有关 MySQL 日期函数的更多信息,请查看reference。 使用这些函数,您可以按星期几、日期、星期、月份和年份生成报告。

【讨论】:

我完全同意; MySQL 具有各种内置的日期数据类型,专门用于简化数学运算。如果您实现自己的表格来存储日期,您将不得不自己做所有这些困难的数学运算(这是闰年吗?是否有闰秒?等等)。让 MySQL 为您做这件事要容易得多,而且它大大简化了您的数据库结构。这个答案有一个很好的建议解决方案I 非常感谢斯隆指出正确的方向!我切换了我的数据库来使用它,它使一切变得更干净、更容易使用。如果我可以投票,我仍然需要获得声誉。 :)

以上是关于用于跟踪全年销售的 SQL 关系数据库的主要内容,如果未能解决你的问题,请参考以下文章

R语言data.table进行滚动数据连接,滚动连接通常用于分析涉及时间的数据(例如商业销售活动和对应的广告投放的安排之之间的关系)实战:实战和动画说明滚动数据连接的形式及方法

你如何在 NoSQL 中跟踪记录关系?

多项“首次”落地 腾讯云数据库助力金融机构国产化

实验9-SPSS相关分析-超市销售数据

GO语言(三十):访问关系型数据库(上)

CRM系统的功能模块有哪些