2012-07-11 12 views
8

Nie spodziewałem się, że to będzie tak trudne, ale próbuję ustawić zmienną użytkownika w MySQL, aby zawierała tablicę wartości. Nie mam pojęcia, jak to zrobić, więc próbowałem robić badania i byłem zaskoczony, że nie znajduję odpowiedzi. Próbowałem:jak ustawić tablicę jako zmienną użytkownika mysql

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

Powodem jest chciałbym użyć zmiennej w następującym stwierdzeniem później:

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; 

byłby bardzo wdzięczny za pomoc.


Przewijanie do przodu jakiś czas, skończyło się z poniższym szybki i brudny roztwór, który nie daje mi elastyczność ponownego wykorzystania tablicę gdzie indziej w kodzie, ale hej, to jest unchargeable zadaniem administratora więc don nie chcę spędzać więcej czasu na tym.

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 wydaje się znaleźć najbardziej eleganckie rozwiązanie (nie testowałem to sobie jeszcze), ale następnym razem, gdy piszę coś, co wywołuje za to będę pamiętał go przetestować!

+2

W SQL nie ma czegoś takiego jak tablice - są tylko zestawy. Niestety, to, co próbujesz, nie działa - mysql zastąpi @billtable_types zawartością twojej "tablicy" jako pojedynczym ciągiem monolitycznym i nie potraktuje jej jako zestawu oddzielnych wartości rozdzielanych przecinkami. Spróbuj użyć funkcji 'FIND_IN_SET()' zamiast operatora 'IN'. –

Odpowiedz

11

Wystarczy znaleźć odpowiedź tutaj: 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

słowo kluczowe "in" nie istnieje 'Kod błędu: 1064 Wystąpił błąd w składni SQL; sprawdź instrukcję, która odpowiada twojej wersji serwera MySQL dla właściwej składni do użycia w pobliżu 'in @billable_types) ' – Mindwin

0

Jak wspomniano Marc B, nie ma zmienną tablicową w MySQL.

Alternatywą find_in_set rozwiązaniem jest użycie SELECT z UNII symulować tablicy:

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

Więc twoja wola zapytań wygląda tak:

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

Ponieważ wątek ten ponownie się pojawił, zmienię moje oryginalne pytanie i dodam, co zrobiłem. –

0

Jeśli użytkownik ma uprawnienie CREATE TABLE, można symulować tablicę, tworząc tymczasową tablicę z jedną kolumną. Wartość lub wartości w tabeli można pobrać za pomocą instrukcji SELECT. Tabele tymczasowe są usuwane pod koniec sesji, ale warto je upuścić, gdy nie będą już potrzebne.

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; 
Powiązane problemy