简体   繁体   English

使用不存在插入和嵌套选择语句的SQL

[英]SQL using insert and nested select statements where not exists

I am doing a Work in Progress summary that feeds graphs for my boss, he wants to store the data so the graphs can show comparisons last year, last quarter, last month and today. 我正在做一个进行中的摘要,该摘要为老板提供图表,他想存储数据,以便图表可以显示去年,上季度,上个月和今天的比较。

I had a couple sql statements that handle this fine but I was trying to consolidate into one statement. 我有几个可以很好处理的sql语句,但是我试图将其合并为一个语句。

SQL: SQL:

INSERT INTO `wip_summary` (`wk_num`, `year`, `a_cnt`, `ae_cnt`, `b_cnt`, `sm_cnt`, `xx_cnt`, `tm_cnt`, `svc_cnt`, `ci_cnt`, `a_amt`, `ae_amt`, `b_amt`, `tm_amt`, `sm_amt`, `xx_amt`, `svc_amt`, `ci_amt`)
   SELECT
      WEEK(CURDATE()),
      YEAR(CURDATE()),
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 10000
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN 1 ELSE 0 END) AS `a_cnt`,
      SUM(CASE WHEN `emc` = 1 THEN 1 ELSE 0 END) AS `ae_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 3500
                  AND `c_price` < 10000
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN 1 ELSE 0 END) AS `b_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 600
                  AND `c_price` < 3500
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN 1 ELSE 0 END) AS `sm_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` < 600
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN 1 ELSE 0 END) AS `xx_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `contractInstall` = '0'
                  AND `terms` = 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN 1 ELSE 0 END) AS `tm_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `wo_type` = 'SERVICE ORDER'
                  AND `contractInstall` = '0'
          THEN 1 ELSE 0 END) AS `svc_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `contractInstall` = '1'
          THEN 1 ELSE 0 END) AS `ci_cnt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 10000
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN `c_price` ELSE 0 END) AS `a_amt`,
      SUM(CASE WHEN `emc` = 1 THEN `c_price` ELSE 0 END) AS `ae_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 3500
                  AND `c_price` < 10000
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN `c_price` ELSE 0 END) AS `b_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `contractInstall` = '0'
                  AND `terms` = 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN `c_price` ELSE 0 END) AS `tm_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` >= 600
                  AND `c_price` < 3500
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN `c_price` ELSE 0 END) AS `sm_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `c_price` < 600
                  AND `contractInstall` = '0'
                  AND `terms` <> 'TIME AND MATERIAL'
                  AND `wo_type` <> 'SERVICE ORDER'
          THEN `c_price` ELSE 0 END) AS `xx_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `wo_type` = 'SERVICE ORDER'
                  AND `contractInstall` = '0'
          THEN `c_price` ELSE 0 END) AS `svc_amt`,
      SUM(CASE WHEN `emc` = '0'
                  AND `contractInstall` = '1'
          THEN `c_price` ELSE 0 END) AS `ci_amt`
    FROM (SELECT CAST(REPLACE(REPLACE(`contract_price`, ',', ''), '$', '') AS Decimal(10,2)) AS `c_price`,
                 `emc`,
                 `contractInstall`,
                 `wo_type`,
                 `terms`
            FROM `orders`
    WHERE `auth_status` = 'ACTIVE') AS `cp_tbl`
WHERE NOT EXISTS (SELECT 1 FROM `wip_summary` WHERE `wk_num` = WEEK(CURDATE()) AND `year` = YEAR(CURDATE()));

What I am doing broken down: 我在做什么分解:

  1. Check to see if the records for this week in this year are in the database 检查以查看今年本周的记录是否在数据库中
  2. Getting the count or summing the dollar amount based on specified criteria 根据指定条件获取计数或求和金额

It works great unless the week and year are in the table, then I get a row of column defaults. 除非表中的星期和年份都很好,否则我会得到一列默认列。

So the WHERE NOT EXISTS is what is failing me but I can't seem to put my finger on why or how. 因此,“ WHERE NOT EXISTS存在”是令我失望的原因,但我似乎无法对为什么或如何做出决定。

Without the nested SELECT statement the INSERT ... WHERE NOT EXISTS works, without the INSERT ... WHERE NOT EXISTS statement the SELECT statement works. 如果没有嵌套的SELECT语句,则INSERT ... WHERE NOT EXISTS起作用,而如果没有INSERT ... WHERE NOT EXISTS语句,则SELECT语句起作用。

Replace the second WHERE with AND. 用AND替换第二个WHERE。 If you don't the Select will always produce data. 如果不这样做,“选择”将始终产生数据。 If you do, the select won't give data, because the year/weak combination already exists in the wip_summary. 如果这样做,则选择将不会提供数据,因为wip_summary中已经存在年份/弱组合。

Change this part: 更改此部分:

        FROM `orders`
    WHERE `auth_status` = 'ACTIVE') AS `cp_tbl`
WHERE NOT EXISTS (SELECT 1 FROM `wip_summary` WHERE `wk_num` = WEEK(CURDATE()) AND `year` = YEAR(CURDATE()));

to

        FROM `orders`
    WHERE `auth_status` = 'ACTIVE') 
    AND NOT EXISTS 
(SELECT 1 FROM `wip_summary` WHERE `wk_num` = WEEK(CURDATE()) AND `year` = YEAR(CURDATE()))
AS `cp_tbl`;

I was able to resolve by adding a SELECT * FROM () statement wrapping the complex one I had. 我可以通过添加一个SELECT * FROM ()语句来解决我遇到的复杂问题来解决。

INSERT INTO `wip_summary` (`wk_num`, `year`, `a_cnt`, `ae_cnt`, `b_cnt`, `sm_cnt`, `xx_cnt`, `tm_cnt`, `svc_cnt`, `ci_cnt`, `a_amt`, `ae_amt`, `b_amt`, `tm_amt`, `sm_amt`, `xx_amt`, `svc_amt`, `ci_amt`)
   SELECT * FROM (SELECT
      WEEK(CURDATE()),
      YEAR(CURDATE()),
      SUM(CASE WHEN `emc` = '0' [...]) AS `a_cnt`,
      SUM(CASE WHEN `emc` =  1  [...]) AS `ae_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `b_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `sm_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `xx_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `tm_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `svc_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `ci_cnt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `a_amt`,
      SUM(CASE WHEN `emc` =  1  [...]) AS `ae_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `b_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `tm_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `sm_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `xx_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `svc_amt`,
      SUM(CASE WHEN `emc` = '0' [...]) AS `ci_amt`
    FROM (SELECT [...] AS `c_price`,
                 `emc`,
                 `contractInstall`,
                 `wo_type`,
                 `terms`
            FROM `orders`
            WHERE `auth_status` = 'ACTIVE') AS `cp_tbl`) AS `vals`
WHERE NOT EXISTS (SELECT 1 FROM `wip_summary` WHERE `wk_num` = WEEK(CURDATE()) AND `year` = YEAR(CURDATE()));

I may be wrong, but I believe the issue was that the SELECT statement that represented the values conflicted with the INSERT 's WHERE clause. 我可能是错的,但我认为问题在于表示值的SELECT语句与INSERTWHERE子句冲突。

The WHERE inside the FROM statement had no conflict, when I removed it and simplified the FROM it still worked the same (inserting a row whether a record was present or not). FROM语句中的WHERE没有冲突,当我删除它并简化FROM它仍然可以正常工作(无论是否存在记录,都插入一行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM