sql >> Database teknologi >  >> RDS >> Mysql

MySql PHP vælg antal forskellige værdier fra kommaseparerede data (tags)

Løsning

Jeg ved ikke rigtig, hvordan man transformerer en vandret liste med kommaseparerede værdier til en liste med rækker uden at oprette en tabel, der indeholder tal, lige så mange tal som du måske har kommaseparerede værdier. Hvis du kan oprette denne tabel, her er mit svar:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(alle_tags, ',', num), ',', -1) AS one_tag, COUNT(*) AS cntFROM ( SELECT GROUP_CONCAT(tags separator ',') AS all_tags, LENGTH (GROUP_CONCAT(tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tags FRA test) tJOIN-tal nON n.num <=t.count_tagsGROUP BY one_tagORDER BY cnt DESC;

Returnerer:

+---------------------+-----+| one_tag | cnt |+----------------------+-----+| kylling | 5 || svinekød | 4 || spaghetti | 3 || stegte ris | 2 || manchurin | 2 || pho | 1 || kylling-calzone | 1 || fettuccine | 1 || chorizo ​​| 1 || frikadeller | 1 || miso-suppe | 1 || chanko-nabe | 1 || kylling-manchurian | 1 || svine-manchurian | 1 || sødt-surt-svinekød | 1 || peking-and | 1 || and | 1 |+---------------------+-----+17 rækker i sæt (0,01 sek.)

Se sqlfiddle

Forklaring

Scenarie

  1. Vi sammenkæder alle tags ved hjælp af et komma for kun at oprette én liste med tags i stedet for én pr. række
  2. Vi tæller, hvor mange tags vi har på vores liste
  3. Vi finder, hvordan vi kan få én værdi på denne liste
  4. Vi finder ud af, hvordan vi kan få alle værdier som adskilte rækker
  5. Vi tæller tags grupperet efter deres værdi

Kontekst

Lad os bygge dit skema:

CREATE TABLE test ( id INT PRIMARY KEY, tags VARCHAR(255));INSERT INTO test VALUES ("1", "pho,pork"), ("2", "fried-rice, chicken" ), ("3", "stegte ris, svinekød"), ("4", "kylling-calzone, kylling"), ("5", "fettuccine, kylling"), ("6", "spaghetti, kylling"), ("7", "spaghetti, chorizo"), ("8", "spaghetti, frikadeller"), ("9", "miso-suppe"), ("10", "chanko- nabe"), ("11", "kylling-manchurian, kylling, manchurin"), ("12", "svine-manchurian, svinekød, manchurin"), ("13", "sød-og-surt-svinekød, svinekød"), ("14", "peking-and, and"); 

Sæt alle lister over tags sammen

Vi vil arbejde med alle tags på en enkelt linje, så vi bruger GROUP_CONCAT for at udføre jobbet:

SELECT GROUP_CONCAT(tags SEPARATOR ',') FROM test; 

Returnerer alle tags adskilt af et komma:

Tæl alle tags

For at tælle alle tags får vi længden af ​​den fulde liste af tags, og vi fjerner længden af ​​den fulde liste af tags efter at have erstattet , ved ingenting. Vi tilføjer 1, da separatoren er mellem to værdier.

SELECT LENGTH(GROUP_CONCAT(tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tagsFROM test; 

Returnerer:

+-------------+| count_tags |+-------------+| 28 |+------------+1 række i sæt (0,00 sek.)

Få det N. tag i taglisten

Vi bruger SUBSTRING_INDEX funktion for at få

-- returnerer strengen indtil 2. skilletegns forekomst fra venstre mod højre:a,bSELECT SUBSTRING_INDEX('a,b,c', ',', 2);-- returner strengen indtil den 1. skilletegn, fra højre mod venstre:cSELECT SUBSTRING_INDEX('a,b,c', ',', -1);-- vi har brug for begge for at få:b (hvor 2 er tagnummeret)SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( 'a,b,c', ',', 2), ',', -1); 

Med sådan logik, for at få det 3. tag på vores liste, bruger vi:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(tags SEPARATOR ','), ',', 3), ',', -1)FRA test; 

Returnerer:

+------------------------------------------------ ------------------------------------------+| SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(tags SEPARATOR ','), ',', 3), ',', -1) |+--------------------------- -------------------------------------------------- --------------+| stegte ris |+----------------------------------------------------- ----------------------------------------+1 række i sæt (0,00 sek.)

Få alle værdier som adskilte rækker

Min idé er lidt tricky:

  1. Jeg ved, at vi kan oprette rækker ved at forbinde tabeller
  2. Jeg har brug for at få det N. tag på listen ved hjælp af anmodningen ovenfor

Så vi opretter en tabel, der indeholder alle tal fra 1 til det maksimale antal tags, du kan have på din liste. Hvis du kan have 1 mio. værdier, skal du oprette 1 mio. poster fra 1 til 1.000.000. For 100 tags vil dette være:

OPRET TABEL numre ( num INT PRIMÆR NØGLE); INDSÆT I tal VÆRDIER ( 1 ), ( 2 ), ( 3 ), ( 4 ), ( 5 ), ( 6 ), ( 7 ), ( 8 ). ), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31), (32), (33) ), (34), (35), (36), (37), (38), (39), (40), (41), (42), (43), (44), (45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58) ), (59), (60), (61), (62), (63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), (81), (82), (83) ), (84), (85), (86), (87), (88), (89), (90), (91), (92), (93), (94), (95), ( 96 ), ( 97 ), ( 98 ), ( 99 ), ( 100 ); 

Nu får vi num th (tal er en række i nummer ) ved hjælp af følgende forespørgsel:

SELECT n.num, SUBSTRING_INDEX(SUBSTRING_INDEX(alle_tags, ',', num), ',', -1) som one_tagFROM ( SELECT GROUP_CONCAT(tags SEPARATOR ',') AS all_tags, LENGTH(GROUP_CONCAT( tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tags FRA test) tJOIN-numre ikke n.num <=t.count_tags

Returnerer:

+-----+----------------------------+| antal | one_tag |+-----+----------------------+| 1 | pho || 2 | svinekød || 3 | stegte ris || 4 | kylling || 5 | stegte ris || 6 | svinekød || 7 | kylling-calzone || 8 | kylling || 9 | fettuccine || 10 | kylling || 11 | spaghetti || 12 | kylling || 13 | spaghetti || 14 | chorizo ​​|| 15 | spaghetti || 16 | frikadeller || 17 | miso-suppe || 18 | chanko-nabe || 19 | kylling-manchurian || 20 | kylling || 21 | manchurain || 22 | svine-manchurian || 23 | svinekød || 24 | manchurin || 25 | sød-sur-flæsk || 26 | svinekød || 27 | peking-and || 28 | and |+-----+---------------------+28 rækker i sæt (0,01 sek.)

Tæl tags-forekomster

Så snart vi nu har klassisk rækker, kan vi nemt tælle forekomster af hvert tag.

Se toppen af ​​dette svar for at se anmodningen.



  1. Ukendt kolonne i 'feltliste', når den forberedte sætnings pladsholder er i underforespørgsel

  2. 5 Fordele ved proaktiv overvågning af databaseydelse

  3. Forberedt Statement Cache med MySQL &JDBC

  4. En oversigt over databasediagramværktøjer, der er tilgængelige til PostgreSQL