समाधान
मैं वास्तव में नहीं जानता कि अल्पविराम से अलग किए गए मानों की एक क्षैतिज सूची को पंक्तियों की सूची में कैसे बदलना है, बिना संख्याओं वाली तालिका बनाए, जितनी संख्या में आपके पास अल्पविराम से अलग किए गए मान हो सकते हैं। यदि आप यह तालिका बना सकते हैं, तो मेरा उत्तर यह है:
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;
रिटर्न:
+---------------------+-----+
| 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)
देखें sqlfiddle
व्याख्या
परिदृश्य
- हम सभी टैग को अल्पविराम का उपयोग करके एक पंक्ति में एक के बजाय टैग की केवल एक सूची बनाने के लिए संयोजित करते हैं
- हम गिनते हैं कि हमारी सूची में कितने टैग हैं
- हम पाते हैं कि हम इस सूची में एक मान कैसे प्राप्त कर सकते हैं
- हम पाते हैं कि हम सभी मानों को अलग-अलग पंक्तियों के रूप में कैसे प्राप्त कर सकते हैं
- हम टैग को उनके मान के आधार पर गिनते हैं
संदर्भ
आइए आपका स्कीमा बनाएं:
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");
टैग की सभी सूची को संयोजित करें
हम सभी टैग के साथ एक ही पंक्ति में काम करेंगे, इसलिए हम GROUP_CONCAT
. का उपयोग करते हैं काम करने के लिए:
SELECT GROUP_CONCAT(tags SEPARATOR ',') FROM test;
कॉमा से अलग किए गए सभी टैग लौटाता है:
सभी टैग गिनें
सभी टैग गिनने के लिए, हमें टैग की पूरी सूची की लंबाई मिलती है, और हम ,
को बदलने के बाद टैग की पूरी सूची की लंबाई को हटा देते हैं। कुछ नही। हम 1 जोड़ते हैं, क्योंकि विभाजक दो मानों के बीच होता है।
SELECT LENGTH(GROUP_CONCAT(tags SEPARATOR ',')) - LENGTH(REPLACE(GROUP_CONCAT(tags SEPARATOR ','), ',', '')) + 1 AS count_tags
FROM test;
रिटर्न:
+------------+
| count_tags |
+------------+
| 28 |
+------------+
1 row in set (0.00 sec)
टैग सूची में Nth टैग प्राप्त करें
हम SUBSTRING_INDEX
. का उपयोग करते हैं
-- 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);
इस तरह के तर्क के साथ, हमारी सूची में तीसरा टैग प्राप्त करने के लिए, हम इसका उपयोग करते हैं:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(tags SEPARATOR ','), ',', 3), ',', -1)
FROM test;
रिटर्न:
+-------------------------------------------------------------------------------------+
| SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(tags SEPARATOR ','), ',', 3), ',', -1) |
+-------------------------------------------------------------------------------------+
| fried-rice |
+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
सभी मानों को अलग पंक्तियों के रूप में प्राप्त करें
मेरा विचार थोड़ा पेचीदा है:
- मुझे पता है कि हम टेबल से जुड़कर पंक्तियां बना सकते हैं
- मुझे उपरोक्त अनुरोध का उपयोग करके सूची में Nth टैग प्राप्त करने की आवश्यकता है
इसलिए हम एक तालिका बनाएंगे जिसमें 1 से लेकर आपकी सूची में मौजूद अधिकतम टैग तक की सभी संख्याएं होंगी। यदि आपके पास 1M मान हो सकते हैं, तो 1 से 1,000,000 तक 1M प्रविष्टियाँ बनाएँ। 100 टैग के लिए, यह होगा:
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 );
अब, हमें num
. मिलता है वें (संख्या number
में एक पंक्ति है ) निम्नलिखित क्वेरी का उपयोग करके:
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
रिटर्न:
+-----+---------------------+
| 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)
टैग की पुनरावृत्तियों की गणना करें
जैसे ही अब हमारे पास क्लासिक . है पंक्तियों में, हम आसानी से प्रत्येक टैग की घटनाओं की गणना कर सकते हैं।
देखें इस उत्तर में सबसे ऊपर अनुरोध देखने के लिए।