2012-07-11 10 views
8

Non mi aspettavo di trovarlo così difficile, ma sto cercando di impostare una variabile utente in MySQL per contenere una matrice di valori. Non ho idea di come farlo, quindi ho cercato di fare qualche ricerca ed è stato abbastanza sorpreso di non trovare risposta. Ho provato:come impostare un array come variabile utente mysql

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

Il motivo vorrei utilizzare la variabile nella seguente dichiarazione in seguito:

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; 

sarei molto grato per l'aiuto.


Fast forward di un po ', ho finito con la seguente soluzione rapida e sporca, che non mi dà la flessibilità di riutilizzare la matrice in altre parti del codice, ma hey è un compito amministratore unchargeable così ho don voglio passare più tempo su di esso.

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 sembra aver trovato la soluzione più elegante (non ancora testato io stesso) ma la prossima volta sto scrivendo qualcosa che chiede per questo mi ricorderò di provarlo!

+2

non c'è niente come matrici in SQL - ci sono solo set. Sfortunatamente, ciò che stai cercando non funziona: mysql sostituirà @billtable_types con il contenuto del tuo "array" come una singola stringa monolitica e non lo considererà come un insieme di valori separati da virgola. Prova a utilizzare la funzione 'FIND_IN_SET()' invece dell'operatore 'IN'. –

risposta

11

appena trovato la risposta qui: 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

la parola chiave "in" non esiste 'Codice errore: 1064 Si ha un errore nella sintassi SQL; controlla il manuale che corrisponde alla tua versione del server MySQL per la sintassi corretta da usare vicino a 'in @billable_types) ' – Mindwin

0

Come Marc B detto, non v'è alcuna variabile di matrice in MySQL.

L'alternativa a find_in_set soluzione è quella di utilizzare SELEZIONA con UNION per simulare la matrice:

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

Così la vostra volontà di query sembra che:

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

Mentre questo thread è emerso di nuovo, modifico la mia domanda originale e aggiungo quello che ho finito per fare. –

0

Se il l'utente ha il privilegio CREATE TABLE, una matrice può essere simulata creando una tabella temporanea a colonna singola. Un valore o valori nella tabella possono essere recuperati con un'istruzione SELECT. Le tabelle temporanee vengono eliminate alla fine della sessione, ma è una buona idea abbandonarle esplicitamente quando non sono più necessarie.

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; 
Problemi correlati