2012-07-11 8 views
8

Ich habe nicht erwartet, dass dies so schwer zu finden, aber ich versuche, eine Benutzervariable in MySQL zu setzen, um ein Array von Werten zu enthalten. Ich habe keine Ahnung, wie ich das machen soll, habe also versucht, etwas zu recherchieren und war ziemlich überrascht, keine Antwort zu finden. Ich habe versucht:Wie setze ich ein Array als mysql Benutzervariable

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

Der Grund dafür möchte ich später auf die Variable in der folgenden Aussage verwenden:

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; 

Wäre sehr dankbar für die Hilfe.


Vorspulen eine Weile, landete ich mit der folgenden quick and dirty Lösung auf, die mir nicht gibt die Flexibilität der Wiederverwendung den Arrays an anderer Stelle im Code, aber hey, es ist eine nicht aufladbar Admin-Aufgabe so dass ich don Ich will keine Zeit mehr damit verbringen.

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 scheint die eleganteste Lösung gefunden zu haben (es nicht selbst noch nicht getestet), aber das nächste Mal, wenn ich bin etwas zu schreiben, die für diese Anrufe ich es zu testen erinnern!

+2

Es gibt keine Arrays in SQL - es gibt nur Sätze. Leider funktioniert das, was Sie versuchen, nicht - mysql wird @billtable_types durch den Inhalt Ihres "Arrays" als eine einzige monolithische Zeichenfolge ersetzen und es nicht als eine Menge separater kommagetrennter Werte betrachten. Versuchen Sie es mit der 'FIND_IN_SET()' -Funktion anstelle des 'IN'-Operators. –

Antwort

11

gefunden einfach die Antwort hier: 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

Das Schlüsselwort "in" existiert nicht. Fehlercode: 1064 Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, um die richtige Syntax in der Nähe von @billable_types zu verwenden. – Mindwin

0

Als Marc B erwähnt, gibt es kein Array-Variable in MYSQL ist.

Die Alternative zu FIND_IN_SET Lösung ist SELECT mit UNION verwenden das Array zu simulieren:

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

So wird Ihre Anfrage so aussieht:

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

Da dieser Thread wieder aufgetaucht ist, werde ich meine ursprüngliche Frage bearbeiten und hinzufügen, was ich getan habe. –

0

Wenn die Benutzer verfügt über die Berechtigung CREATE TABLE. Ein Array kann simuliert werden, indem eine temporäre Tabelle mit nur einer Spalte erstellt wird. Ein Wert oder Werte in der Tabelle können mit einer SELECT-Anweisung abgerufen werden. Temporäre Tabellen werden am Ende der Sitzung gelöscht, es ist jedoch eine gute Idee, sie explizit zu löschen, sobald sie nicht mehr benötigt werden.

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; 
Verwandte Themen