2012-03-07 16 views
6

Ho a che fare con il sistema telefonico e devo lavorare con più fornitori di servizi. Per un unico fornitore Ho una tabella di MySQL country_codes come questo -Aggiornare record specifici della tabella MySQL

--------------------------------------------------------- 
country_code | area_code | country 
--------------------------------------------------------- 
93   | 93   | Afghanistan 
0    | 9375  | Afghanistan Cellular-AT 
0    | 9370  | Afghanistan Cellular-AWCC 
355   | 355  | Albania 
0    | 35568  | Albania Cellular-AMC 
0    | 35567  | Albania Cellular-Eagle 
213   | 213  | Algeria 
0    | 21377  | Algeria Cellular-Djezzy 
0    | 2135  | Algeria Cellular-Wataniya 
--------------------------------------------------------- 

e così via ...

La colonna country_code prima non c'era, ma ho aggiunto che da quando ne avevo bisogno per la mia applicazione PHP. Sono riuscito ad aggiornare i codici paese per alcuni record (utilizzando la risposta dalla mia domanda precedente qui)

Quello che voglio ottenere è sostituire gli 0 con il rispettivo codice paese. Quindi la tabella dovrebbe essere simile a questa -

--------------------------------------------------------- 
country_code | area_code | country 
--------------------------------------------------------- 
93   | 93   | Afghanistan 
93   | 9375  | Afghanistan Cellular-AT 
93   | 9370  | Afghanistan Cellular-AWCC 
355   | 355  | Albania 
355   | 35568  | Albania Cellular-AMC 
355   | 35567  | Albania Cellular-Eagle 
213   | 213  | Algeria 
213   | 21377  | Algeria Cellular-Djezzy 
213   | 2135  | Algeria Cellular-Wataniya 
--------------------------------------------------------- 

Spero ho spiegato io stesso abbastanza bene. Qualche idea su come posso farlo con PHP-MySQL?

(non mi dispiace utilizzando il codice PHP per manipolare la tabella in questo modo)

+0

È possibile utilizzare la relazione tra area_code e country_code per popolare il country_code (Parte di area_code è il tuo paese_code) –

+0

Ho bisogno di un po 'più di informazioni. Come possiamo dire cosa rende un codice paese valido? Poiché a volte sono a 2 cifre ea volte a 3 cifre, non possiamo semplicemente tagliare la fine del prefisso. Hai già inserito tutti i codici paese validi almeno una volta su tutti i 28.000 record? – Andrew

+0

Sembra che ogni "azienda" abbia un prefisso che inizia con il prefisso assegnato al "Paese", corretto? Questo modello funziona con l'intero set di dati? –

risposta

6

Prova questa ricerca -

UPDATE country_codes 
SET country_code := @c := IF(@c IS NOT NULL AND country_code = 0, @c, country_code) 
ORDER BY CAST(area_code AS CHAR) 
+0

country_code può essere minimo di 1 cifra e massimo di 4 cifre – skos

+0

SUBSTRING (area_code, 1, 3) non restituirà più di 3 caratteri (cifre). stringa in caso di vuoto 'area_code'. Hai vuoto 'area_code'? – Devart

+0

Nessun 'area_code' non può mai essere vuoto – skos

0

Qualcosa del genere dovrebbe funzionare, a patto di avere un database chiamato "testdb", e una tabella chiamata "footable".

$link = mysql_connect("localhost", "username", "password1234"); 
mysql_select_db("testdb", $link); 

$result = mysql_query("UPDATE footable SET country_code="93" WHERE country LIKE Afghanistan%", $link); 
$result = mysql_query("UPDATE footable SET country_code="355" WHERE country LIKE Albania%", $link); 

mysql_close($link); 
+1

Credo che questo sia l'opposto di ciò che @Sachyn sta chiedendo. –

+0

@Adam, ci sono molti più Paesi in quella tabella, ciò che ha mostrato sono solo dati di esempio. –

+0

@NaveenKumar Considera un caso di una riga in cui il paese è "UK-Orange" e il codice paese i 0, ma l'unica voce esistente è "Regno Unito" ... Se i dati sono semplici e prevedibili, l'approccio automatizzato "indovina" può essere preso - ma questo accade raramente nel mondo reale. – Adam

2
update cc set 
    country_code = t.country_code 
from country_codes cc 
join (
    select country_code, country, char_length(trim(cast(country_code as char))) as code_len 
    from country_codes 
    where country_code <> 0 
) t on 
    t.country_code = cast(substr(cast(cc.area_code as char), 1, t.code_len) as signed integer) and 
    cc.country_code = 0 and 
    cc.country like concat(t.country, '%') 

Ho aggiunto cc.country like concat(t.country, '%') a condizione di essere più precisi, ma si presume che ogni nome di rete cellulare inizia con il suo nome di paese - quindi se non è vero ometterlo.

Aggiunto dopo @Sachyn commento:

codice

di prova utilizzato su SQLZOO funziona bene, è per il test solo, non è una query di aggiornamento:

select cc.*, t.country_code as new_country_code 
from (
    select 93 as country_code, 93 as area_code , 'Afghanistan' as country union 
    select 0 , 9375 , 'Afghanistan Cellular-AT' union 
    select 0 , 9370 , 'Afghanistan Cellular-AWCC' union 
    select 355, 355 , 'Albania' union 
    select 0 , 35568, 'Albania Cellular-AMC' union 
    select 0 , 35567, 'Albania Cellular-Eagle' union 
    select 213, 213 , 'Algeria' union 
    select 0 , 21377, 'Algeria Cellular-Djezzy' union 
    select 0 , 2135 , 'Algeria Cellular-Wataniya' 
) cc 
join (
    select country_code, country, char_length(rtrim(cast(country_code as char))) as code_len 
    from (
     select 93 as country_code, 93 as area_code , 'Afghanistan' as country union 
     select 0 , 9375 , 'Afghanistan Cellular-AT' union 
     select 0 , 9370 , 'Afghanistan Cellular-AWCC' union 
     select 355, 355 , 'Albania' union 
     select 0 , 35568, 'Albania Cellular-AMC' union 
     select 0 , 35567, 'Albania Cellular-Eagle' union 
     select 213, 213 , 'Algeria' union 
     select 0 , 21377, 'Algeria Cellular-Djezzy' union 
     select 0 , 2135 , 'Algeria Cellular-Wataniya' 
    ) c 
    where country_code <> 0 
) t on 
    t.country_code = cast(substr(cast(cc.area_code as char), 1, t.code_len) as signed integer) and 
    cc.country_code = 0 and 
    cc.country like concat(t.country, '%') 
+0

Grazie Michal, ho provato, ma mi dà questo errore '# 1064 - Hai un errore nella sintassi SQL; controlla il manuale che corrisponde alla tua versione del server MySQL per la sintassi corretta da usare vicino a 'country_codes cc join (seleziona country_code, country, char_length (trim (' alla riga 3' – skos

+0

Questo è l'approccio corretto dato che le ipotesi dichiarate sono corrette - Devi solo giocare con la sintassi per farlo funzionare – Stevo

+0

@Sachyn usi questa query così com'è? L'ho provato e dovrebbe funzionare bene Prova la mia ultima versione forse qualcosa è cambiato nel frattempo. –

0

È possibile creare un tavolo con countries in LY, cioè .:

INSERT INTO countries (country_code,country) 
SELECT country_code,country FROM country_codes WHERE country_code=0 

allora si può facilmente aggiornare il vostro tavolo

UPDATE country_codes cc, countries c 
SET cc.country_code = c.country_code 
WHERE LOCATE(c.country,cc.country)=1 AND cc.country_code=0 

non ho ancora testato questo, ma credo che si può ottenere il punto.

1

Se avete bisogno di fare la correzione dei dati una sola volta, si può provare questo approccio:

0) backup dei dati, o meglio, eseguire la query sulla copia dei dati.

1) Crea una tabella che contiene codici paese diversi da zero. Abbiamo bisogno di tabella a parte, perché si dice nel manuale di MySQL che:

Attualmente, non è possibile aggiornare una tabella e selezionare dalla stessa tabella in una sottoquery.

CREATE TABLE country_codes_list (
    country_code INT NOT NULL PRIMARY KEY 
); 

INSERT INTO country_codes_list 
SELECT country_code 
FROM country_codes 
WHERE country_code <> 0; 

2) Aggiornare tutte le righe in cui il codice paese? 0, trovando il codice del paese che corrisponde all'inizio del prefisso:

UPDATE country_codes AS country_codes_zero SET country_code = (
    SELECT country_code 
    FROM country_codes_list 
    WHERE country_codes_list.country_code = SUBSTRING(country_codes_zero.area_code, 1, LENGTH(country_codes_list.country_code)) 
) WHERE country_code = 0; 

Questa potrebbe essere una query molto lenta perché utilizza una sotto-query correlata. Ma dovrebbe risolvere i dati in un colpo solo.

Problemi correlati