社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
私信  •  关注

spencer7593

spencer7593 最近创建的主题
spencer7593 最近回复了
6 年前
回复了 spencer7593 创建的主题 » 使用mysql生成当前30、60、90天的老化报告

指定给表达式的别名 SELECT 列表不能在 选择 列表,或 WHERE 条款。(它可供以后在语句处理中引用,在 HAVING 条款或 ORDER BY 条款)

一种方法(可能很昂贵)是使用内联视图,在其中提供别名,然后在外部查询中,可以将指定的别名作为列名引用。

SELECT v.my_alias 
  FROM ( -- inline view 
         SELECT t.foo AS my_alias 
           FROM ...
       ) v

例如

SELECT v.INV_NUM
     , v.INV_DDATE
     , v.days_past_due
     , v.total_ar
     , SUM(IF( v.days_past_due = 0               ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN  1 AND 30 ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN 31 AND 60 ,v.total_ar,0))
     , SUM(IF( v.days_past_due BETWEEN 61 AND 90 ,v.total_ar,0))
     , SUM(IF( v.days_past_due > 90              ,v.total_ar,0))
  FROM (
         SELECT t.INV_NUM
              , t.INV_DDATE
              , DATEDIFF(CURDATE(), FROM_UNIXTIME(t.INV_DDATE)) AS `days_past_due`
              , t.INV_DBAL                                      AS `total_ar`
           FROM invoice_table t
          WHERE t.INV_CODE = 'the_client code'
       ) v

这可能很昂贵,因为MySQL在运行外部查询之前处理内联视图、创建和填充中间表(称为“派生表”)的方式。


除此之外,我们的选择是重复同样的表达来推导“过期天数”,例如。

SELECT t.INV_NUM
     , t.INV_DDATE
     , DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) AS `days_past_due`
     , t.INV_DBAL                                     AS `total_ar`
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) = 0               ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN  1 AND 30 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN 31 AND 60 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) BETWEEN 61 AND 90 ,t.INV_DBAL,0))
     , SUM(IF( DATEDIFF(CURDATE(),FROM_UNIXTIME(t.INV_DDATE)) > 90              ,t.INV_DBAL,0))
  FROM invoice_table t
 WHERE t.INV_CODE = 'the_client code'
6 年前
回复了 spencer7593 创建的主题 » mysql left join返回意外结果

我会使用条件聚合。对单个引用的联接 tall_comment_votes ,然后检查表达式中的条件。

SELECT c.id
     , SUM(IF(v.status = 1                                          ,1,0)) AS upvotes
     , SUM(IF(v.status = 1 AND v.user_id = 1 AND v.is_anonymous = 0 ,1,0)) AS userUpvoted
     , SUM(IF(v.status = 2                                          ,1,0)) AS downvotes
     , SUM(IF(v.status = 2 AND v.user_id = 1 AND v.is_anonymous = 0 ,1,0)) AS userDownvoted
  FROM talk_comments c
  LEFT
  JOIN talk_comment_votes v
    ON v.comment_id = c.id
 WHERE c.id = 2
 GROUP
    BY c.id

这避免了当v1、v2、v3和v4返回多行时部分交叉积的问题。

MySQL IF() 表达式可以替换为更符合ANSI标准的 CASE 表达式,例如

    , SUM(CASE WHEN v.status = 1 THEN 1 ELSE 0 END)  AS upvotes

追随

设置测试用例并遵守执行计划和性能

填充表

CREATE TABLE talk_comments (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT);
CREATE TABLE talk_comment_votes (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, comment_id  INT UNSIGNED NOT NULL, user_id  INT UNSIGNED NOT NULL, is_anonymous TINYINT(1) UNSIGNED NOT NULL, STATUS TINYINT UNSIGNED, time_ INT UNSIGNED); 
CREATE INDEX talk_comment_votes_IX1 ON talk_comment_votes (comment_id, STATUS, user_id, is_anonymous) ;
INSERT INTO talk_comments (id) VALUES (1),(2),(3);
INSERT INTO talk_comment_votes (id, comment_id, user_id, is_anonymous, STATUS, time_) VALUES (1,2,2,0,1,0),(2,1,1,0,1,0),(3,2,1,0,2,NULL),(4,7,1,0,2,NULL),(5,1,14,1,1,NULL),(6,2,14,1,1,NULL);

查询执行计划

EXPLAIN
SELECT c.id, COUNT(DISTINCT v1.id) AS upvotes, COUNT(DISTINCT v2.id) AS userUpvoted, COUNT(DISTINCT v3.id) AS downvotes, COUNT(DISTINCT v4.id) AS userDownvoted FROM talk_comments c
  LEFT JOIN talk_comment_votes v1 ON v1.comment_id = c.id AND v1.status = 1 
    LEFT JOIN talk_comment_votes v2 ON v2.comment_id = c.id AND v2.status = 1 AND v2.user_id = 1 AND v2.is_anonymous = 0
    LEFT JOIN talk_comment_votes v3 ON c.id = v3.comment_id AND v3.status = 2
    LEFT JOIN talk_comment_votes v4 ON c.id = v4.comment_id AND v4.status = 2 AND v4.user_id = 1 AND v4.is_anonymous = 0
WHERE c.id = 2 GROUP BY c.id
;

EXPLAIN
SELECT c.id
     , SUM(IF(v.status = 1                                          ,1,0)) AS upvotes
     , SUM(IF(v.status = 1 AND v.user_id = 1 AND v.is_anonymous = 0 ,1,0)) AS userUpvoted
     , SUM(IF(v.status = 2                                          ,1,0)) AS downvotes
     , SUM(IF(v.status = 2 AND v.user_id = 1 AND v.is_anonymous = 0 ,1,0)) AS userDownvoted
    FROM talk_comments c
    LEFT
    JOIN talk_comment_votes v
      ON v.comment_id = c.id
   WHERE c.id = 2
   GROUP BY c.id
;

explain的输出

--     id  select_type  table   type    possible_keys           key                     key_len  ref                        rows  Extra        
-- ------  -----------  ------  ------  ----------------------  ----------------------  -------  -----------------------  ------  -------------
--      1  SIMPLE       c       const   PRIMARY                 PRIMARY                 4        const                         1  Using index  
--      1  SIMPLE       v1      ref     talk_comment_votes_IX1  talk_comment_votes_IX1  6        const,const                   2  Using index  
--      1  SIMPLE       v2      ref     talk_comment_votes_IX1  talk_comment_votes_IX1  11       const,const,const,const       1  Using index  
--      1  SIMPLE       v3      ref     talk_comment_votes_IX1  talk_comment_votes_IX1  6        const,const                   1  Using index  
--      1  SIMPLE       v4      ref     talk_comment_votes_IX1  talk_comment_votes_IX1  11       const,const,const,const       1  Using index  



--     id  select_type  table   type    possible_keys           key                     key_len  ref       rows  Extra        
-- ------  -----------  ------  ------  ----------------------  ----------------------  -------  ------  ------  -------------
--      1  SIMPLE       c       const   PRIMARY                 PRIMARY                 4        const        1  Using index  
--      1  SIMPLE       v       ref     talk_comment_votes_IX1  talk_comment_votes_IX1  4        const        3  Using index  

测量性能:

100 executions                        round 1      round 2     round 3
------------------------------------  ----------   ----------  ---------
multiple left join, count(distinct    0.123 secs   0.130 secs  0.125 secs
conditional aggregation sum(if        0.113 secs   0.114 secs  0.111 secs
6 年前
回复了 spencer7593 创建的主题 » mysql按排序列值选择多个列组

我们只需要表达式对n1、n2和n3列中的值进行“排序”。如果我们有,我们可以做一个简单的 GROUP BY COUNT .

SELECT COUNT(1) AS total
     , IF(t.n1<=t.n2,IF(t.n1<=t.n3,t.n1,t.n3),IF(t.n2<=t.n3,t.n2,t.n3)) AS n1s
     , IF(t.n1<=t.n2,IF(t.n2<=t.n3,t.n2,IF(t.n1<=t.n3,t.n3,t.n1)),IF(t.n1<=t.n3,t.n1,IF(t.n2<=t.n3,t.n3,t.n2 ))) AS n2s
     , IF(t.n1<=t.n2,IF(t.n2<=t.n3,t.n3,t.n2),IF(t.n1<=t.n3,t.n3,t.n1)) AS n3s
  FROM this_table_column_structure t
 GROUP BY n1s,n2s,n3s
 ORDER BY total DESC, n1s, n2s, n3s

将返回

total   n1s   n2s   n3s
-----  ----  ----  ----
    2     1     2     3
    2     5     6     7
    1     1     5     6
    1     3     5     6
6 年前
回复了 spencer7593 创建的主题 » 如何插入另一个表mysql中的数据[关闭]

对于中的现有行 member ,假设 to from inbox sent 表包含 id 来自的值 成员 表,然后我们可以从中获取相关行的计数 收件箱 发送 ,并将计数存储到 成员 表,包含如下内容:

UPDATE `member` m 
   SET m.inbox = ( SELECT COUNT(1) FROM `inbox` i ON i.to   = m.id )
     , m.sent  = ( SELECT COUNT(1) FROM `sent`  s ON s.from = m.id )

这个例子提出了各种无根据的假设…什么是“数据量”,收件箱和发送到成员表的表之间的关系,…

如果没有示例数据和预期的最终结果,我们只是在猜测规范,而我们提出的任何SQL都只是猜测。

当没有合适的索引时,在大型集合上相关子查询的性能可能会有问题。还有其他的查询模式将获得同等的结果。