Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySql PHP pilih jumlah nilai yang berbeda dari data yang dipisahkan koma (tag)

Solusi

Saya tidak benar-benar tahu cara mengubah daftar horizontal nilai yang dipisahkan koma menjadi daftar baris tanpa membuat tabel yang berisi angka, sebanyak mungkin angka yang Anda miliki dengan nilai yang dipisahkan koma. Jika Anda dapat membuat tabel ini, inilah jawaban saya:

SELECT 
  SUBSTRING_INDEX(SUBSTRING_INDEX(all_tags, ',', num), ',', -1) AS one_tag,
  COUNT(*) AS cnt
FROM (
  SELECT
    GROUP_CONCAT(tags separator ',') AS all_tags,
    LENGTH(GROUP_CONCAT(tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tags
  FROM test
) t
JOIN numbers n
ON n.num <= t.count_tags
GROUP BY one_tag
ORDER BY cnt DESC;

Pengembalian:

+---------------------+-----+
| one_tag             | cnt |
+---------------------+-----+
| chicken             |   5 |
| pork                |   4 |
| spaghetti           |   3 |
| fried-rice          |   2 |
| manchurain          |   2 |
| pho                 |   1 |
| chicken-calzone     |   1 |
| fettuccine          |   1 |
| chorizo             |   1 |
| meat-balls          |   1 |
| miso-soup           |   1 |
| chanko-nabe         |   1 |
| chicken-manchurian  |   1 |
| pork-manchurian     |   1 |
| sweet-and-sour-pork |   1 |
| peking-duck         |   1 |
| duck                |   1 |
+---------------------+-----+
17 rows in set (0.01 sec)

Lihat sqlfiddle

Penjelasan

Skenario

  1. Kami menggabungkan semua tag menggunakan koma untuk membuat hanya satu daftar tag, bukan satu per baris
  2. Kami menghitung berapa banyak tag yang kami miliki di daftar kami
  3. Kami menemukan bagaimana kami bisa mendapatkan satu nilai dalam daftar ini
  4. Kami menemukan bagaimana kami bisa mendapatkan semua nilai sebagai baris yang berbeda
  5. Kami menghitung tag yang dikelompokkan berdasarkan nilainya

Konteks

Mari buat skema Anda:

CREATE TABLE test (
    id INT PRIMARY KEY,
    tags VARCHAR(255)
);

INSERT INTO test VALUES
    ("1",         "pho,pork"),
    ("2",         "fried-rice,chicken"),
    ("3",         "fried-rice,pork"),
    ("4",         "chicken-calzone,chicken"),
    ("5",         "fettuccine,chicken"),
    ("6",         "spaghetti,chicken"),
    ("7",         "spaghetti,chorizo"),
    ("8",         "spaghetti,meat-balls"),
    ("9",         "miso-soup"),
    ("10",        "chanko-nabe"),
    ("11",        "chicken-manchurian,chicken,manchurain"),
    ("12",        "pork-manchurian,pork,manchurain"),
    ("13",        "sweet-and-sour-pork,pork"),
    ("14",        "peking-duck,duck");

Menggabungkan semua daftar tag

Kami akan bekerja dengan semua tag dalam satu baris, jadi kami menggunakan GROUP_CONCAT untuk melakukan pekerjaan:

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

Mengembalikan semua tag yang dipisahkan dengan koma:

Hitung semua tag

Untuk menghitung semua tag, kami mendapatkan panjang daftar lengkap tag, dan kami menghapus panjang daftar lengkap tag setelah mengganti , tanpa apa pun. Kami menambahkan 1, karena pemisah berada di antara dua nilai.

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

Pengembalian:

+------------+
| count_tags |
+------------+
|         28 |
+------------+
1 row in set (0.00 sec)

Dapatkan tag ke-N di daftar tag

Kami menggunakan SUBSTRING_INDEX berfungsi untuk mendapatkan

-- returns the string until the 2nd delimiter\'s occurrence from left to right: a,b
SELECT SUBSTRING_INDEX('a,b,c', ',', 2);

-- return the string until the 1st delimiter, from right to left: c
SELECT SUBSTRING_INDEX('a,b,c', ',', -1);

-- we need both to get: b (with 2 being the tag number)
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a,b,c', ',', 2), ',', -1);

Dengan logika seperti itu, untuk mendapatkan tag ke-3 dalam daftar kami, kami menggunakan:

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

Pengembalian:

+-------------------------------------------------------------------------------------+
| SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(tags SEPARATOR ','), ',', 3), ',', -1) |
+-------------------------------------------------------------------------------------+
| fried-rice                                                                          |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Dapatkan semua nilai sebagai baris berbeda

Ide saya agak rumit:

  1. Saya tahu kita bisa membuat baris dengan menggabungkan tabel
  2. Saya perlu mendapatkan tag ke-N dalam daftar menggunakan permintaan di atas

Jadi kami akan membuat tabel yang berisi semua angka dari 1 hingga jumlah maksimum tag yang mungkin Anda miliki di daftar Anda. Jika Anda dapat memiliki 1 juta nilai, buat 1 juta entri dari 1 hingga 1.000.000. Untuk 100 tag, ini akan menjadi:

CREATE TABLE numbers (
  num INT PRIMARY KEY
);

INSERT INTO numbers VALUES
    ( 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 );

Sekarang, kita mendapatkan num th (angka menjadi baris dalam number ) menggunakan kueri berikut:

SELECT n.num, SUBSTRING_INDEX(SUBSTRING_INDEX(all_tags, ',', num), ',', -1) as one_tag
FROM (
  SELECT
    GROUP_CONCAT(tags SEPARATOR ',') AS all_tags,
    LENGTH(GROUP_CONCAT(tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tags
  FROM test
) t
JOIN numbers n
ON n.num <= t.count_tags

Pengembalian:

+-----+---------------------+
| num | one_tag             |
+-----+---------------------+
|   1 | pho                 |
|   2 | pork                |
|   3 | fried-rice          |
|   4 | chicken             |
|   5 | fried-rice          |
|   6 | pork                |
|   7 | chicken-calzone     |
|   8 | chicken             |
|   9 | fettuccine          |
|  10 | chicken             |
|  11 | spaghetti           |
|  12 | chicken             |
|  13 | spaghetti           |
|  14 | chorizo             |
|  15 | spaghetti           |
|  16 | meat-balls          |
|  17 | miso-soup           |
|  18 | chanko-nabe         |
|  19 | chicken-manchurian  |
|  20 | chicken             |
|  21 | manchurain          |
|  22 | pork-manchurian     |
|  23 | pork                |
|  24 | manchurain          |
|  25 | sweet-and-sour-pork |
|  26 | pork                |
|  27 | peking-duck         |
|  28 | duck                |
+-----+---------------------+
28 rows in set (0.01 sec)

Hitung kemunculan tag

Segera setelah kami memiliki klasik baris, kita dapat dengan mudah menghitung kemunculan setiap tag.

Lihat bagian atas jawaban ini untuk melihat permintaan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 2 Kotak masukan pelengkapan otomatis/saran menggunakan jQuery atau Ajax dengan kotak kedua berdasarkan pilihan pertama dengan banyak item

  2. LOAD DATA INFILE Kode Kesalahan:13

  3. Apakah mungkin untuk GROUP BY beberapa kolom menggunakan MySQL?

  4. Cara memberi makan kueri mysql dari bash

  5. MySQL Hapus Duplikat Catatan