如何将数组设置为mysql用户变量

Posted

技术标签:

【中文标题】如何将数组设置为mysql用户变量【英文标题】:how to set an array as a mysql user variable 【发布时间】:2012-07-10 14:49:10 【问题描述】:

我没想到会这么难,但我试图在 mysql 中设置一个用户变量来包含一个值数组。我不知道如何做到这一点,所以尝试做一些研究,但很惊讶没有找到答案。我试过了:

SET @billable_types = ['client1','client2','client3'];

原因是我想稍后在以下语句中使用该变量:

SELECT sum((time_to_sec(timediff(tlg.time_stop, tlg.time_start))/3600)) as billable_hours
    from mod_tmlog_time_log tlg, mod_tmlog_task_list mttl
    where date(tlg.time_start) >= @time_start
          and date(tlg.time_stop) <= @time_stop
          and mttl.type IN (@billable_types)
            and tlg.task_id = mttl.id
    group by start_date
    order by start_date desc;

非常感谢您的帮助。


快进一会儿,我最终得到了以下快速而肮脏的解决方案花更多的时间在上面。

SELECT WEEKDAY(tlg.time_start) AS day_of_week, date(tlg.time_start) as start_date,
                            sum((time_to_sec(timediff(tlg.time_stop, tlg.time_start))/3600)) as billable_hours
                    from mod_tmlog_time_log tlg, mod_tmlog_task_list mttl
                    where date(tlg.time_start) >= @time_start
                          and date(tlg.time_stop) <= @time_stop
                          and mttl.type IN ('c1','c2','c3')
                            and tlg.task_id = mttl.id
                    group by start_date
                    order by start_date desc;

joostschouten 似乎找到了最优雅的解决方案(我自己还没有测试过),但下次我写需要这个的东西时,我会记得测试它!

【问题讨论】:

SQL 中没有数组这样的东西——只有集合。不幸的是,您尝试做的不起作用-mysql会将@billtable_types 替换为您的“数组”的内容作为单个整体字符串,而不是将其视为一堆单独的逗号分隔值。尝试使用FIND_IN_SET() 函数而不是IN 运算符。 【参考方案1】:

刚刚在这里找到答案:How to cycle with an array in MySQL?

set @billable_types = 'client1,client2,client3';
select * from mttl where find_in_set(mttl.type, @billable_types);

【讨论】:

“in”关键字不存在Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'in @billable_types)【参考方案2】:

正如 Marc B 所说,MYSQL 中没有数组变量。

find_in_set 解决方案的替代方案是使用 SELECTUNION 来模拟数组:

SELECT billable_type FROM (
  SELECT 'client1' AS billable_type UNION
  SELECT 'client2' AS billable_type UNION
  SELECT 'client3' AS billable_type) AS t

所以您的查询将如下所示:

SELECT sum((time_to_sec(timediff(tlg.time_stop, tlg.time_start))/3600)) as billable_hours
     from mod_tmlog_time_log tlg, mod_tmlog_task_list mttl
     where date(tlg.time_start) >= @time_start
          and date(tlg.time_stop) <= @time_stop
          and mttl.type IN (

            SELECT billable_type FROM (
              SELECT 'client1' AS billable_type UNION
              SELECT 'client2' AS billable_type UNION
              SELECT 'client3' AS billable_type) AS t

          )
             and tlg.task_id = mttl.id
     group by start_date
     order by start_date desc;

【讨论】:

随着这个话题再次浮出水面,我将编辑我原来的问题并添加我最终做的事情。【参考方案3】:

如果用户具有 CREATE TABLE 权限,则可以通过创建临时单列表来模拟数组。可以使用 SELECT 语句检索表中的一个或多个值。临时表在会话结束时被删除,但最好在不再需要它们时显式删除它们。

CREATE TEMPORARY TABLE billable_types (c VARCHAR(16));
INSERT INTO billable_types VALUES ('client1'), ('client2'), ('client3');

SELECT sum((time_to_sec(timediff(tlg.time_stop, tlg.time_start))/3600)) as billable_hours
from mod_tmlog_time_log tlg, mod_tmlog_task_list mttl
where date(tlg.time_start) >= @time_start
      and date(tlg.time_stop) <= @time_stop
      and mttl.type IN (SELECT * FROM billable_types)
        and tlg.task_id = mttl.id
group by start_date
order by start_date desc;

DROP TABLE billable_types;

【讨论】:

以上是关于如何将数组设置为mysql用户变量的主要内容,如果未能解决你的问题,请参考以下文章

mysql 变量设置问题

mysql 变量设置问题

如何设置mysql的权限为所有的用户权限

如何将简单的 SQL 查询存储到用户定义的变量中并在 MySQL 中执行?

如何将数组存储到mysql中?

如何设置mysql用户的权限