输出中只有一个日期列的SQL子查询

时间:2015-07-01 02:14:15

标签: mysql sql

如果我选择TVS中的TV_DATE,我该如何修改此代码?

  SELECT TV_DATE, 
        CASE WHEN t5.O_UP BETWEEN 1 AND 3 THEN 5 ELSE O_WT=0 END as O_WT,
        CASE WHEN t5.O_RE BETWEEN 3 AND 5 THEN  6 ELSE 0 END as O_RD_WT,
        CASE WHEN t5.OR_RD BETWEEN 5 AND 10 THEN 5 ELSE 0 END as OR_RD_WT,
        CASE WHEN t5.OR_U_RD BETWEEN 20 AND 30 THEN 3 ELSE 0 END as OR_U_RD_WT 


    SELECT TV_DATE, 
        CASE 
            WHEN t5.O_UP BETWEEN 1 AND 3 THEN 5 
            ELSE 0 
        END AS O_WT,
        CASE 
            WHEN t5.O_RE BETWEEN 3 AND 5 THEN 6 
            ELSE 0 
        END AS O_RD_WT,
        CASE 
            WHEN t5.OR_RD BETWEEN 5 AND 10 THEN 5 
            ELSE 0 
        END AS OR_RD_WT,
        CASE 
            WHEN t5.OR_U_RD BETWEEN 20 AND 30 THEN 3 
            ELSE 0 
        END AS OR_U_RD_WT  
FROM
    (
        SELECT  COALESCE(t1.O_UPDATE,0) AS O_UP, 
                COALESCE(t2.O_READ,0) AS O_RE, 
                COALESCE(t3.OR_READ,0) AS OR_RD, 
                COALESCE(t4.OR_U_READ,0) AS OR_U_RD 
        FROM
        (
            SELECT SUM(TV_R_U_COUNT) as O_UPDATE from TVS where TV_T_NAME='abcd' AND TV_DATE between '2015-01-01' and '2015-07-01' AND TV_R_U='U' AND TV_I_NAME LIKE 'w1%we%' AND TV_I_NAME like 'we%avd%'
        ) t1,
        (
            SELECT SUM(TV_R_U_COUNT) as O_READ from TVS where TV_T_NAME='abcd' AND TV_DATE between '2015-01-01' and '2015-07-01' AND TV_R_U='X' AND TV_I_NAME LIKE 'w1%we%' AND TV_I_NAME like 'er%dfr%'
        ) t2,
        (
            SELECT SUM(TV_R_U_COUNT) as OR_READ from TVS where TV_T_NAME='abcd' AND TV_DATE between '2015-01-01' and '2015-07-01' AND TV_R_U='X' AND TV_I_NAME LIKE 'w1%we%' AND TV_I_NAME like 'cv%dfr%' AND TV_I_NAME NOT LIKE 'dsf%er%'
        ) t3,
        (
            SELECT SUM(TV_R_U_COUNT) as OR_U_READ from TVS where TV_T_NAME='abcd' AND TV_DATE between '2015-01-01' and '2015-07-01' AND TV_R_U='X' AND TV_I_NAME LIKE 'w1%we%' AND TV_I_NAME like 'ad%asd%ere'
        ) t4
    ) t5,
     TVS 

我可以请求一些帮助来解决这个问题吗?

我希望获得以下类型的输出。

+-------------+------+---------+----------+------------+------------+
|    DATE     | O_WT | O_RD_WT | OR_RD_WT | OR_U_RD_WT | OR_U_RD_WT |
+-------------+------+---------+----------+------------+------------+
| 2015-01-01  |    5 |       6 |        4 |          3 |          0 |
| 2015-01-02  |    5 |       0 |        0 |          3 |          0 |
| 2015-01-03  |    5 |       0 |        0 |          0 |          0 |
| 2015-01-04  |    5 |       6 |        4 |          0 |          0 |
| 2015-01-05  |    5 |       0 |        0 |          3 |          0 |
+-------------+------+---------+----------+------------+------------+

我在SELECT语句之间尝试了UNION,但它混淆了输出。输出肯定是错误的。不能想到如何使这个工作: - (

1 个答案:

答案 0 :(得分:3)

考虑到在各个内联视图中重复谓词(t1,t2,t3,t4),并且假设你想要返回"计数"在同一行,我会对tvs表使用单个查询,并使用"条件聚合"。

我使用具有条件测试的表达式,并仅在该条件为真时返回tv_r_u_count,并将其包装在聚合函数中。例如:

SUM(IF(tv_r_u = 'U' AND t.tv_i_name LIKE 'we%avd%', tv_r_u_count, NULL))

看起来你也想要对结果进行条件测试......如果它在1到3之间然后返回5.

您提出的问题,如何返回tv_date。看起来您希望根据每个tv_date生成计数总和。为此,我们会在查询中添加GROUP BY tv_date,并在tv_date列表中返回SELECT

正如我在您对您的问题的评论中所指出的,您的查询中的某些谓词是互斥的。也就是说,如果

 foo LIKE 'w1%we%'

评估为TRUE,我们知道

 foo LIKE 'we%avd%'

将返回FALSE。与AND结合使用时,即TRUE AND FALSE将永远不会返回TRUE。 (我希望您的至少其中一个条件包含一个额外的通配符,例如前导%字符,因此AND条件有可能返回TRUE。

我会使用类似下面的查询生成指定的结果。

我故意缩进,为)"排队"做出结束工作SUM(。在同一列中。我对CASE表达式进行了类似的缩进。空白行不是必需的,但我这样做是为了突出显示条件测试,表达式之间发生变化的部分,表达式的其余部分重复(除了分配给列的别名。)

 SELECT t.date
      , CASE WHEN
          SUM(
            CASE WHEN

              t.tv_r_u = 'U' AND t.tv_i_name LIKE 'we%avd%'

            THEN t.tv_r_u_count END
          ) BETWEEN  1 AND  3 THEN 5 ELSE 0
        END AS o_wt
      , CASE WHEN
          SUM(
            CASE WHEN

              t.tv_r_u = 'X' AND t.tv_i_name LIKE 'er%dfr%'

            THEN t.tv_r_u_count END
          ) BETWEEN  3 AND  5 THEN 6 ELSE 0
        END AS o_rd_wt
      , CASE WHEN
          SUM(
            CASE WHEN

              t.tv_r_u = 'X' AND t.tv_i_name LIKE 'cv%dfr%' AND t.tv_i_name NOT LIKE 'dsf%er%'

            THEN t.tv_r_u_count END
          ) BETWEEN  5 AND 10 THEN 5 ELSE 0
        END AS or_rd_wt
      , CASE WHEN
          SUM(
            CASE WHEN

              t.tv_r_u = 'X' AND t.tv_i_name LIKE 'ad%asd%ere'

            THEN t.tv_r_u_count END
          ) BETWEEN 20 AND 30 THEN 3 ELSE 0
        END AS or_u_rd_wt
   FROM tvs t
  WHERE t.tv_t_name = 'abcd'
    AND t.tv_date   BETWEEN '2015-01-01' AND '2015-07-01'
    AND t.tv_r_u    IN ('U','X')
    AND t.tv_i_name LIKE 'w1%we%'
  GROUP BY t.date

请注意,WHERE子句中的某些谓词可以重复(或移动)到SUM()聚合中的条件测试。例如,我们可以删除该行:

    AND t.tv_r_u    IN ('U','X')

并获得等效结果,因为聚合中的条件已经在检查tv_r_u='U'tv_r_u='X'

不同之处在于我们可能会返回更多行,如果在WHERE子句中删除该谓词包含更多行,那么tv_r_u的其他值将具有额外的tv_date值。 ; t出现在'U''X'行。

请注意,将返回的唯一tv_date值是满足WHERE子句中所有谓词的行的值。

作为另一个例子,我们可以重复条件测试

  AND t.tv_t_name = 'abcd'

在SELECT列表中的每个表达式中,然后(可选)将其从WHERE子句中删除。