2012-07-11 76 views
8

我沒有想到會發現這很難,但我試圖在MySQL中設置一個用戶變量來包含一個值的數組。我不知道如何做到這一點,所以試着做一些研究,很驚訝地發現沒有答案。我曾嘗試:如何設置一個數組作爲一個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似乎已經找到了最完美的解決方案(沒有測試它自己還沒有),但我正在寫一些東西,呼籲這個下次我會記得測試一下吧!

+2

有沒有這樣的事情,像SQL中的數組 - 只有集合。不幸的是,你試圖無法工作 - mysql將用你的「數組」的內容替換@billtable_types作爲一個整體字符串,而不會將它視爲一組單獨的逗號分隔值。嘗試使用'FIND_IN_SET()'函數代替'IN'運算符。 – 2012-07-11 03:10:30

回答

11

就找到了答案在這裏: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); 
+1

「in」關鍵字不存在錯誤代碼:1064 您的SQL語法錯誤;查看與你的MySQL服務器版本相對應的手冊,在'@billable_types'附近使用正確的語法)' – Mindwin 2014-02-05 14:17:28

0

正如馬克B中提及的,存在MYSQL沒有數組變量。

FIND_IN_SET解決方案的替代方案是使用選擇UNION模擬陣列:

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; 
+0

由於這個線程已經浮出水面,我將編輯我的原始問題並添加我最終做的事情。 – 2014-05-09 05:28:06

0

如果用戶具有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; 
相關問題