CASE的WHERE子句无法识别第二种情况

时间:2019-01-07 00:21:51

标签: mysql

我在内部Join中使用以下Case子句作为MAX值id上的WHERE条件,Case查询仅根据第一个条件给我结果> lasteditor!=“ abc@example.com”不为空然后lasteditor!=“ abc@example.com”。

我想做的是,如果lasteditor!=“ abc@example.com”为空,则使用lasteditor =“ abc@example.com”否则将abc@example.com忽略为lasteditor并获取下一封lasteditor电子邮件< / p>

                WHERE 
                    CASE WHEN 
                        lasteditor != "abc@example.com" IS NOT NULL
                            THEN
                                lasteditor != "abc@example.com"
                    WHEN
                        lasteditor != "abc@example.com" IS NULL
                            THEN 
                                lasteditor = "abc@example.com"

                    ELSE NULL END                   

我想做的是,在LastEditor不是abc@example.com的任何其他行上进行内部联接,但是,如果LastEditor不是abc@example.com,则根本没有结果,然后获取abc@example.com所在的行

    INNER JOIN (SELECT MAX(id) AS maxid,dyna_id,LastEditor FROM t2

        WHERE 
                CASE WHEN t2.lasteditor != "abc@example.com" IS NOT NULL
                    THEN t2.lasteditor != "abc@example.com"
                    WHEN t2.lasteditor != "abc@example.com" IS NULL
                    THEN t2.lasteditor = "abc@example.com"

                    ELSE NULL END

    GROUP BY t2.dyna_id) AS history ON main.id = history.dyna_id

摘要

                WHERE t2.lasteditor = (CASE
                WHEN t2.lasteditor != 'abc@example.com' --- if rows exists --- THEN 'abc@example.com' (if rows exists after skipping rows where lasteditor is abc@example.com then use this case)
                WHEN t2.lasteditor != 'abc@example.com' --- if no rows exists --- THEN pick up the rows where 'abc@example.com' is the last editor
                END)

下面的代码做到了,我想它做到了,它正在处理一个巨大的表,希望它显示正确的结果

                    WHERE
                        CASE
                            WHEN
                            lasteditor <> "abc@example.com" IS NOT NULL
                            THEN
                                lasteditor <> "abc@example.com"
                                ELSE
                                lasteditor <> "test"
                            END
                            GROUP BY
                            hist.dyna_id

下面的完整查询

            SELECT
               "Total",
               COUNT(IF(main.case_status = "OPEN", 1, NULL)) AS "open_cases",
               COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "0 Star" 
                     AND main.tm_perception < "3 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "0 Star" 
                     AND main.tl_perception < "3 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "0 Star" 
                     AND main.owner_perception < "3 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "0 Star" 
                     AND main.owner_perception < "3 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "bb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "2 Star" 
                     AND main.tm_perception < "5 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "2 Star" 
                     AND main.tl_perception < "5 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "2 Star" 
                     AND main.owner_perception < "5 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "2 Star" 
                     AND main.owner_perception < "5 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "mb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "4 Star" 
                     AND main.tm_perception < "6 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "4 Star" 
                     AND main.tl_perception < "6 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "4 Star" 
                     AND main.owner_perception < "6 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "4 Star" 
                     AND main.owner_perception < "6 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "tb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "na" 
                  THEN
                     main.id 
                  ELSE
                     NULL 
               END
            ) AS "na" 
            FROM
               gt AS main 
               LEFT JOIN
                  frontend_forms_users AS caseowner 
                  ON main.se_v_9 = caseowner.alias 
               INNER JOIN
                  (
                     SELECT
                        MAX(id) AS maxid,
                        dyna_id AS dn 
                     FROM
                        history_gt hist 
                     WHERE
                        CASE
                           WHEN
                              lasteditor <> "abc@example.com" IS NOT NULL 
                           THEN
                              lasteditor <> "abc@example.com" 
                           ELSE
                              lasteditor <> "test" 
                        END
                     GROUP BY
                        hist.dyna_id 
                  )
                  AS history 
                  ON main.id = dn 
               LEFT JOIN
                  history_gt AS owner2 
                  ON maxid = owner2.id 
               LEFT JOIN
                  frontend_forms_users AS owner 
                  ON owner2.LastEditor = owner.primary_email 
            UNION ALL
            SELECT
               caseowner.attr_lob AS lob,
               COUNT(IF(main.case_status = "OPEN", 1, NULL)) AS "open_cases",
               COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "0 Star" 
                     AND main.tm_perception < "3 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "0 Star" 
                     AND main.tl_perception < "3 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "0 Star" 
                     AND main.owner_perception < "3 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "0 Star" 
                     AND main.owner_perception < "3 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "bb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "2 Star" 
                     AND main.tm_perception < "5 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "2 Star" 
                     AND main.tl_perception < "5 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "2 Star" 
                     AND main.owner_perception < "5 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "2 Star" 
                     AND main.owner_perception < "5 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "mb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "TM" 
                     AND main.tm_perception > "4 Star" 
                     AND main.tm_perception < "6 Star" 
                  THEN
                     main.tm_perception 
                  WHEN
                     owner.attr_role = "TL" 
                     AND main.tl_perception > "4 Star" 
                     AND main.tl_perception < "6 Star" 
                  THEN
                     main.tl_perception 
                  WHEN
                     owner.attr_role = "SE" 
                     AND main.owner_perception > "4 Star" 
                     AND main.owner_perception < "6 Star" 
                  THEN
                     main.owner_perception 
                  WHEN
                     owner.attr_role = "SE2" 
                     AND main.owner_perception > "4 Star" 
                     AND main.owner_perception < "6 Star" 
                  THEN
                     main.owner_perception 
                  ELSE
                     NULL 
               END
            ) AS "tb", COUNT( 
               CASE
                  WHEN
                     owner.attr_role = "na" 
                  THEN
                     main.id 
                  ELSE
                     NULL 
               END
            ) AS "na" 
            FROM
               gt AS main 
               LEFT JOIN
                  frontend_forms_users AS caseowner 
                  ON main.se_v_9 = caseowner.alias 
               INNER JOIN
                  (
                     SELECT
                        MAX(id) AS maxid,
                        dyna_id AS dn 
                     FROM
                        history_gt hist 
                     WHERE
                        CASE
                           WHEN
                              lasteditor <> "abc@example.com" IS NOT NULL 
                           THEN
                              lasteditor <> "abc@example.com" 
                           ELSE
                              lasteditor <> "test" 
                        END
                     GROUP BY
                        hist.dyna_id 
                  )
                  AS history 
                  ON main.id = dn 
               LEFT JOIN
                  history_gt AS owner2 
                  ON maxid = owner2.id 
               LEFT JOIN
                  frontend_forms_users AS owner 
                  ON owner2.LastEditor = owner.primary_email 
            GROUP BY
               lob 
            ORDER BY
               2 DESC

2 个答案:

答案 0 :(得分:0)

以下情况可能会有所帮助。主表是带有作者的文章,针对任何文章,作者或其他任何人都可以评论。我只想显示不是作者的任何人的最新评论,除非只有作者发表了评论

编辑

要显示不是作者的任何人的最新评论-除非只有评论,否则请获取最新的评论。

CREATE TABLE article(
   id     INTEGER  NOT NULL PRIMARY KEY 
  ,author VARCHAR(100) NOT NULL
  ,title  VARCHAR(100) NOT NULL
);
INSERT INTO article(id,author,title)
VALUES 
  (1,'abc@example.com','a first article')
, (2,'def@example.com','beware of between')
, (3,'ghi@example.com','to be or not whatever');
CREATE TABLE comments(
   id         INTEGER  NOT NULL PRIMARY KEY 
  ,article_id INTEGER  NOT NULL
  ,author     VARCHAR(100) NOT NULL
  ,body VARCHAR(200) NOT NULL
);
INSERT INTO comments(id,article_id,author,body) 
VALUES
  (1,1,'abc@example.com','first comment')
, (2,1,'def@example.com','second comment')
, (3,1,'ghi@example.com','third comment')
, (4,1,'abc@example.com','2nd author comment')
, (5,3,'ghi@example.com','only comment')
;

相关查询方法(任何MySQL版本)通过order by case when c.author <> t.author then 1 else 2 end, id DESClimit

select
      a.*
    , c.*
from (
    select
           t.*
         , (select id 
            from comments as c 
            where c.article_id = t.id 
            order by
                  case when c.author <> t.author then 1 else 2 end
                , id DESC
            limit 1) AS max_comment_id
    from article as t
    ) a
left join comments as c on a.max_comment_id = c.id
;
id | author          | title                 | max_comment_id |   id | article_id | author          | body         
-: | :-------------- | :-------------------- | -------------: | ---: | ---------: | :-------------- | :------------
 1 | abc@example.com | a first article       |              3 |    3 |          1 | ghi@example.com | third comment
 2 | def@example.com | beware of between     |           null | null |       null | null            | null         
 3 | ghi@example.com | to be or not whatever |              5 |    5 |          3 | ghi@example.com | only comment 

分组子查询方法(任何MySQL版本)

select
      a.*
    , c.*
from article a
left join (
        select
               c.article_id
             , max(coalesce((case when c.author <> a.author then c.id end), (case when c.author = a.author then c.id end))) max_comment_id
        from comments as c 
        inner join article a on c.article_id = a.id 
        group by
               c.article_id
       ) d on a.id = d.article_id
left join comments c on d.max_comment_id = c.id
;
id | author          | title                 |   id | article_id | author          | body              
-: | :-------------- | :-------------------- | ---: | ---------: | :-------------- | :-----------------
 1 | abc@example.com | a first article       |    4 |          1 | abc@example.com | 2nd author comment
 2 | def@example.com | beware of between     | null |       null | null            | null              
 3 | ghi@example.com | to be or not whatever |    5 |          3 | ghi@example.com | only comment      

具有row_number()的派生表方法(从MySQL 8开始)

select
      a.*
    , c.*
from article a
left join (
          select
               c.*
             , row_number() over(partition by article_id 
                                 order by case when c.author <> a.author then 1 else 2 end, id DESC
                                ) as rn
          from comments as c 
          inner join article a on c.article_id = a.id 
          ) c on a.id = c.article_id and c.rn = 1
id | author          | title                 |   id | article_id | author          | body          |   rn
-: | :-------------- | :-------------------- | ---: | ---------: | :-------------- | :------------ | ---:
 1 | abc@example.com | a first article       |    3 |          1 | ghi@example.com | third comment |    1
 2 | def@example.com | beware of between     | null |       null | null            | null          | null
 3 | ghi@example.com | to be or not whatever |    5 |          3 | ghi@example.com | only comment  |    1

公用表表达式和row_number()方法(从MySQL 8开始)

with max_comments as (
    select
           c.*
         , row_number() over(partition by article_id 
                             order by case when c.author <> a.author then 1 else 2 end, id DESC
                            ) as rn
    from comments as c 
    inner join article a on c.article_id = a.id 
    ) 
select
      a.*
    , c.*
from article a
left join max_comments c on a.id = c.article_id and c.rn = 1
id | author          | title                 |   id | article_id | author          | body          |   rn
-: | :-------------- | :-------------------- | ---: | ---------: | :-------------- | :------------ | ---:
 1 | abc@example.com | a first article       |    3 |          1 | ghi@example.com | third comment |    1
 2 | def@example.com | beware of between     | null |       null | null            | null          | null
 3 | ghi@example.com | to be or not whatever |    5 |          3 | ghi@example.com | only comment  |    1

db <>提琴here

答案 1 :(得分:0)

您的问题,示例联接,子查询没有任何意义...话虽如此,让我尝试以这种方式再次提出您的问题。如果我是正确的话,那么很好,如果不能,那么您的问题需要认真加以澄清。

您有此表“ T2”。在其中,您具有任何给定“ dyna_id”的多个记录。它可能具有1条或更多条记录,并且每个“ ID”都是自动递增的。因此,对于给定的“ Dyna_ID”,您需要该密钥的最新记录。一旦知道每个“ Dyna_ID”实例的最新“ ID”,您就想知道最后一个编辑记录的人是谁。对我来说,这意味着所有记录都将始终有一个编辑帖子的人,除非第一个记录是创建记录并且没有“ addEditor”值并且没有提供“ LastEditor”值(但不要认为这是事实)。是这种情况。)

因此,要获得此结果,它是一个分为两部分的查询。首先,获取给定DYNA_ID的最后一个ID。由此,获取与给定的“ ID”匹配的LastEditor的名称。最后,与其他人加入MAIN的答案相同...

INNER JOIN 
   -- getting the Details for that last edited per Dyna_ID
   (select
         T2.Dyna_id,
         T2.ID,
         coalesce( T2.LastEditor, 'abc@example.com' ) as LastEditorPerDynaID
      from
         T2
            -- getting the last ID for any given Dyna_ID
            JOIN ( select
                         tmp1.dyna_id,
                         max(tmp1.id) as MaxIdPerDynaID
                      from
                         t2 tmp1
                      group by 
                         tmp1.dyna_id ) PQ
               on T2.Dyna_ID = PQ.Dyna_ID
              AND T2.ID = PQ.MaxIdPerDynaID ) history 
   ON main.id = history.dyna_id

在abc@example.com上的澄清

您对abc@example.com的要求。这是“ T2”表的一些示例数据。

ID   Dyna_ID   LastEditor
 1    A         ME
 2    B         abc@example.com
 3    A         HER
 4    C         ME
 5    B         HIM 
 6    A         abc@example.com
 7    A         HIM
 8    C         HER
 9    B         abc@example.com
10    D         abc@example.com

根据上述数据,我具有唯一的Dyna_ID值A,B和C,D。因此,原始查询中的max(ID)和最终对应的Last Editor将导致

Dyna_ID  HighestID  LastEditor
A        7          HIM
B        9          abc@example.com
C        8          HER
D        10         abc@example.com

因此,从此示例数据中,如果您仅查找那些最后一个编辑器不是abc@example.com的那些,则您希望“ B” DynaID提取ID = 5“ HIM”的LastEditor。但是对于“ D” DynaID,他们唯一的记录是“ abc@lexample.com”,没有其他记录,因此可以保留该记录。

如果是这种情况,那么我的内部PQ(预查询)将分别基于“ abc”条目的EITHER条件获得最大ID。因为我们总是会至少有一个条目,但是想要有或没有...的相应最大ID。

INNER JOIN 
   -- getting the Details for that last edited per Dyna_ID
   (select
         T2.Dyna_id,
         T2.ID,

         coalesce( T2.LastEditor, 'abc@example.com' ) as LastEditorPerDynaID
      from
         T2
            -- getting the last ID for any given Dyna_ID
            JOIN 
            ( select
                    PQ1.Dyna_ID,
                    case when PQ1.MaxIdNotAbcEditor > 0
                         then PQ1.MaxIdNotAbcEditor
                         else PQ1.MaxIdAsAbcEditor end as FinalJoinID
                 from
                    ( select
                            tmp1.dyna_id,
                            -- get max ID if NOT the 'abc' editor
                            max( case when NOT tmp1.LastEditor = 'abc@example.com' then tmp1.id else 0 end ) as MaxIdNotAbcEditor,
                            -- get max ID if IT IS the 'abc' editor
                            max( case when tmp1.LastEditor = 'abc@example.com' then tmp1.id else 0 end ) as MaxIdAsAbcEditor
                         from
                            t2 tmp1
                         group by 
                            tmp1.dyna_id ) PQ1 ) PQ
               on T2.Dyna_ID = PQ.Dyna_ID
              AND T2.ID = PQ.FinalJoinID ) history 
   ON main.id = history.dyna_id

基于SECOND查询,它分为三部分。对于任何给定的Dyna_ID,最里面的“ PQ1”预查询1都是基于EITHER相应部分得到的最后一个ID,因此

Dyna_ID  MaxIdNotAbcEditor   MaxIdAsAbcEditor
A        7                   6
B        5                   9
C        8                   0
D        0                  10

可以看出,DynaID“ C”没有“ abc @”记录,因此它的最大ID为Abc编辑器= 0 ... DynaID“ D”的逆。它只有一个“ abc @”,因此对于NOT Abc编辑器为0,对于AS Abc编辑器为10。这是正确的假设吗?

好的。因此,现在,对于任何一个Dyna ID,我们都可以为每种分类提供一个最大值。因此,当创建仅动态ID和最大ID的外部“ PQ”结果时,将使用情况进行包装。如果“我不是abc编辑器”列中有一个值,请使用THAT作为ID。否则,抓住唯一的其他选择...是abc编辑器的条目。结果为

Dyna_ID   FinalJoinID
A         7
B         5
C         8
D         10