【问题标题】:SQL using insert and nested select statements where not exists使用不存在的插入和嵌套选择语句的 SQL
【发布时间】:2015-11-25 15:09:40
【问题描述】:

我正在为我的老板提供图表,他想要存储数据以便图表可以显示去年、上个季度、上个月和今天的比较。

我有几个 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()));

我在做什么分解:

  1. 查看今年本周的记录是否在数据库中
  2. 根据指定条件计算或汇总美元金额

除非星期和年份在表格中,否则效果很好,然后我会得到一行默认值。

所以WHERE NOT EXISTS 是我失败的原因,但我似乎无法确定原因或方式。

没有嵌套的SELECT 语句,INSERT ... WHERE NOT EXISTS 有效,没有INSERT ... WHERE NOT EXISTS 语句,SELECT 语句有效。

【问题讨论】:

  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更容易复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
  • 也许第二个 WHERE 必须用 AND 代替。
  • wk_num 是iso格式的吗? stackoverflow.com/questions/11788885/…
  • @TomV 是的,正如我所提到的,SQL 语句都可以单独工作。在一起就是我遇到问题的时候。

标签: mysql sql


【解决方案1】:

将第二个 WHERE 替换为 AND。 如果您不这样做,则 Select 将始终生成数据。如果这样做,则选择不会提供数据,因为 wip_summary 中已经存在年/弱组合。

改变这部分:

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

        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`;

【讨论】:

  • 第二个WHERE 用于INSERT 语句,第一个WHERE 用于SELECT 语句,如果我用AND 替换第二个,我会得到一个syntax error near 'AND...' mysql错误。
  • 我认为这是有问题的地方,但用 AND 替换并不能解决问题。单独的 SQL 语句可以完美地工作。我可能无法像我希望的那样整合这些陈述,因为冲突就在那里。
  • 您可能已将其更改为 |WHERE auth_status = 'ACTIVE') AS cp_tbl AND 不存在(从 wip_summary 中选择 1@WHERE wk_num = WEEK(CURDATE()) AND year = 年份(CURDATE()));它必须是:|WHERE auth_status = 'ACTIVE') 且不存在(从 wip_summary 中选择 1,其中 wk_num = WEEK(CURDATE()) AND year = YEAR(CURDATE()))为 @987654339 @;
  • 欣赏答案,是的,我试过了。在 SELECT 周围使用括号并使用 AND,不带括号。同样的语法错误。
  • 检查“AS cp_cpl”的位置。它必须在 where 语句之后。
【解决方案2】:

我能够通过添加一个 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()));

我可能错了,但我认为问题在于表示值的 SELECT 语句与 INSERTWHERE 子句冲突。

FROM 语句中的 WHERE 没有冲突,当我删除它并简化 FROM 时,它仍然可以正常工作(无论是否存在记录都插入一行)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多