2015-07-09 7 views
7

Sto scrivendo un software di fidelizzazione della clientela per un club aperto dalle 10 alle 6 di tutti i giorni. I dati sono archiviati in MYSQL e mi piacerebbe contare le visite totali del cliente per il mese.Conteggio SQL di visite distinte di un cliente con orari di apertura dalle 10 alle 6

Sto usando il conteggio (distinto (data)) ma se il giocatore è arrivato alle 17:00 e è rimasto fino alle 3:00 con 2 transazioni alle 22:00 e alle 2:00. Sarà conteggiata come 2 visite invece di 1.

Ho una tabella di transazione con le colonne elencate di seguito:

ps: nulla nei parentesi() non è dati reali. Ottengo circa 2000 transazioni al giorno. Sono anche in grado di modificare la struttura della tabella

 Transaction_ID | Date(not Date/Time) | Customer_ID | Item | price | timestamp 
    1   | 11-06-2015 (6pm) | Jane  | drink| 2.00 | 156165166 
    2   | 09-06-2015 (2pm) | Jane  | drink| 2.00 | 1433858493 
    3   | 10-06-2015 (3am) | Jane  | drink| 2.00 | 1433906073 
    4   | 06-06-2015 (6pm) | Jane  | drink| 2.00 | 156165166 

rendimenti codice corrente {4, Jane}. La risposta che sto cercando è {3, Jane}. Operazione {2,3} dovrebbe essere considerata come una visita

SELECT count(distinct(Date)) as visit, Customer_ID 
FROM transaction 
GROUP BY Customer_ID 
WHERE timestamp BETWEEN $timestamp1 AND $timestamp2 
$timestamp1 = strtotime("first day of february +10am"); 
$timestamp2 = strtotime("first day of march +6am");

Come cosa suggerisce di contare con precisione le visite totali al di sotto? Sono in grado di modificare la struttura della tabella da Data a Data/ora.

La risposta più semplice con meno modifiche ai miei codici.

SELECT count(DISTINCT(DATE(DATE_SUB(from_unixtime(timestamp),INTERVAL 6 HOUR))) as visit, Customer_ID 
FROM transaction 
GROUP BY Customer_ID 
WHERE timestamp BETWEEN $timestamp1 AND $timestamp2 

+0

mostra alcuni dati fittizi. non ottieni quello che vuoi –

+0

Come stai calcolando 'timestamp1' e' timestamp2'? Se devi inserire questi timestamp in puoi anche raggruppare i risultati per ora ed elaborarli in un altro linguaggio di programmazione, che sarà molto più facile da leggere perché gli orari di apertura sono puramente logici applicativi. Seconda possibilità, scorrere il database utilizzando i timestamp per tutti i giorni. – Smutje

+0

Non è necessario eseguire il pasticcio con il fuso orario per sottrarre 6 ore al – Vatev

risposta

1

Il modo più semplice è quello di spostare il vostro datetime campo schiena per 6 ore in un'istruzione SQL e quindi si otterrà un intervallo in un giorno 4:00-12:00 (date, timestamp?):

DISTINCT(DATE(DATE_SUB(dt,INTERVAL 6 HOUR))) 

SQLFiddle demo

+0

'SELECT COUNT (DISTINCT (DATE (DATE_SUB (timestamp, INTERVAL 6 HOUR)))) come visite, player_id FROM transaction WHERE date BETWEEN '2014-10-01' AND '2014-11-01' GROUP BY customer_id ORDINA PER visite LIMITE DEL DESCRIZIONE 25' Non sembra funzionare. 'Date (timestamp)' sembra ritornare nullo o totalmente spento. esempio timestamp: 1412175207 –

+0

@BoonYaoTan usa 'from_unixtime (timestamp)' invece di solo 'timestamp' per convertirlo in valore DATETIME. – valex

+0

GRAZIE FUNZIONA !!!!! –

0

Ecco il codice necessario:

SELECT 
    Customer_ID 'Customer ID' 
    , COUNT(DISTINCT visit) as 'Visits per month' 
    , MONTH(visit) 'Month' 
    , YEAR(visit) 'Year' 
FROM 
    (SELECT 
    * 
    , CASE 
     WHEN (t_timestamp > Date_StartDate AND t_timestamp < Date_EndDate) 
      THEN d_date 
     WHEN (t_timestamp < Date_StartDate) 
      THEN date_add(d_date, INTERVAL -1 DAY) 
     END 'visit' 
    FROM 
    (SELECT * 
     , DATE_ADD(CAST(d_date AS DATETIME), INTERVAL 10 HOUR) Date_StartDate 
     , DATE_ADD(DATE_ADD(cast(d_date AS DATETIME), INTERVAL 6 HOUR), INTERVAL 1 DAY) Date_EndDate 
    FROM transactions) Results 
    ) Results 
GROUP BY customer_id, month(visit), year(visit) 

Inoltre, ecco un SQLFiddle con i risultati del codice.

Non ho usato il formato esatto per il tuo Customer ID (ho usato INTEGER al posto di VARCHAR) e non ho usato le date esatte che hai usato nel tuo esempio, ma ovviamente dovrebbe funzionare per qualsiasi cosa.

Prendere in considerazione la possibilità di regolare il nome delle colonne utilizzate nella query per i nomi di colonna appropriati e si dovrebbe andare bene.

Problemi correlati