Mysql 如何使用单个where子句而不是两个相同的where子句?

Mysql 如何使用单个where子句而不是两个相同的where子句?,mysql,sql,performance,query-optimization,Mysql,Sql,Performance,Query Optimization,我的问题是: SELECT * FROM posts p1 CROSS JOIN (SELECT COUNT(*) cnt, COUNT(amount) cntamt FROM posts p2 WHERE p2.type = 0 OR p2.amount IN ( :vals2 ) OR p2.date_time BETWEEN :s2 AND :e2) t WHERE p1.type

我的问题是:

SELECT * 
FROM posts p1
CROSS JOIN (SELECT COUNT(*) cnt, COUNT(amount) cntamt
            FROM posts p2
            WHERE p2.type = 0
               OR p2.amount IN ( :vals2 )
               OR p2.date_time BETWEEN :s2 AND :e2) t
WHERE p1.type = 0
   OR p1.amount IN ( :vals1 )
   OR p1.date_time BETWEEN :s1 AND :e1
ORDER BY p1.id 
LIMIT 0,2

如您所见,上面的查询中有两个where子句,它们完全相同。现在我想知道,如何使用单个where子句编写查询

这在MySQL中是个难题,因为它不支持CTE。一种解决方案是使用视图。但这是行不通的,因为你有参数

变量是另一种选择

SELECT p.*, @cnt as cnt, @amt as cntamt
FROM (SELECT p.*,
             (@cnt := @cnt + 1) as tmp_cnt,
             (@amt := @amt + (case when amount is not null then 1 else 0 end)) as tmp_amt
      FROM posts p CROSS JOIN 
           (SELECT @cnt := 0, @amt := 0) params
      WHERE p.type = 0 OR
            p.amount IN ( :vals2 ) OR
            p.date_time BETWEEN :s2 AND :e2
     ) t
ORDER by p.id;

COUNT*cnt和COUNTamount的结果是相同的,因此,如果您解释此查询的目的/您试图作为结果获取的内容,可能会有更好的帮助,但目前您可以使用以下内容:


从贴子a中选择*,从贴子分组中按column1、column2 b选择count*、countcolumn1、column1、column2,其中a.column1=b.column1和a.column2=b.column2,其中a.column1=:column1和a.column2 in:column2

您必须在末尾添加过滤。您的查询同样存在性能问题。谢谢。是的,你的方法是正确的,符合预期。根据你的知识,你建议我选哪一个?你的方法是什么?还是我的?@MartinAJ。您可能需要衡量性能并选择一个运行最快的。在poststype、amount、datetime上有一个索引,它们可能相当相似。仅供参考,根据一些基准测试,我发现使用变量的方法对于一个巨大的数据集来说要快两倍。请告诉我在查询中使用交叉连接的原因是什么?这对我来说似乎是多余的。是吗?@MartinAJ。需要一个子查询来定义变量。交叉连接将该子查询连接到查询的其余部分。它们不相同,除非:vals2与:vals1神奇地相同。