मैं MySQL में एक सरणी चर का अनुकरण कैसे कर सकता हूं?


91

ऐसा प्रतीत होता है कि MySQL में सरणी चर नहीं हैं। मुझे इसके बजाय क्या उपयोग करना चाहिए?


सुझाए गए दो विकल्प प्रतीत होते हैं: एक सेट-प्रकार स्केलर और अस्थायी टेबल । प्रश्न मैं पूर्व के सुझाव से जुड़ा हुआ हूं। लेकिन सरणी चर की बजाय इनका उपयोग करना अच्छा है? वैकल्पिक रूप से, अगर मैं सेट के साथ जाता हूं, तो सेट-आधारित मुहावरा किसके बराबर होगा foreach?


2
का उपयोग करें ELT
पचेरियर

1
@ स्पेसर: क्या आप ईएलटी की अधिक क्रिया चर्चा से जुड़ सकते हैं, शायद एक लंबे उदाहरण के साथ?
einpoklum

जवाबों:


76

खैर, मैं सरणी चर के बजाय अस्थायी तालिकाओं का उपयोग कर रहा हूं। सबसे बड़ा समाधान नहीं है, लेकिन यह काम करता है।

ध्यान दें कि आपको अपने खेतों को औपचारिक रूप से परिभाषित करने की आवश्यकता नहीं है, बस उन्हें एक चयन का उपयोग करके बनाएं:

CREATE TEMPORARY TABLE IF NOT EXISTS my_temp_table
SELECT first_name FROM people WHERE last_name = 'Smith';

( क्रिएट टेबल का उपयोग किए बिना चयन कथन से अस्थायी तालिका भी देखें ।)


1
ओह्ह: ओ मुझे नहीं पता था कि एसक्यूएल के पास यह था !! तालिकाएँ केवल प्रश्नों के चलने की गुंजाइश के लिए जीवित हैं। NEAT!
इब्बानम

2
@Yasky, बशर्ते कि आप कनेक्शन का पुन: उपयोग न करें। क्योंकि वास्तव में यह पूरे सत्र तक चलेगा ।
पेसियर

और आप एक अस्थायी तालिका का पुन: उपयोग नहीं कर सकते। तो यह बहुत उपयोगी नहीं है।
जॉन


4
@ जॉन: हाँ, ठीक है, आप इसे पुन: उपयोग कर सकते हैं, लेकिन उसी क्वेरी में नहीं।
ईनपोकलम

46

आप इसे MySQL WHILEलूप का उपयोग करके प्राप्त कर सकते हैं :

SET @myArrayOfValue = '2,5,2,23,6,';

WHILE (LOCATE(',', @myArrayOfValue) > 0)
DO
    SET @value = ELT(1, @myArrayOfValue);
    SET @myArrayOfValue= SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);

    INSERT INTO `EXEMPLE` VALUES(@value, 'hello');
END WHILE;

संपादित करें: वैकल्पिक रूप से आप इसका उपयोग कर सकते हैं UNION ALL:

INSERT INTO `EXEMPLE`
(
 `value`, `message`
)
(
 SELECT 2 AS `value`, 'hello' AS `message`
 UNION ALL
 SELECT 5 AS `value`, 'hello' AS `message`
 UNION ALL
 SELECT 2 AS `value`, 'hello' AS `message`
 UNION ALL
 ...
);

4
केवल संग्रहीत प्रक्रियाओं में लूप संभव नहीं हैं?
einpoklum

2
हाँ ठीक है, संग्रहीत प्रक्रियाओं, कार्यों और ट्रिगर के अंदर इसका संभव।
ओमेश

1
इसलिए मैं आपके द्वारा प्रदान किए गए कोड का उपयोग नहीं कर सकता ... मुझे ऐसी चीज़ की आवश्यकता है जो अधिक सामान्यतः लागू हो।
einpoklum

आप एक नमूना संग्रहीत प्रक्रिया लिख ​​सकते हैं और CALLयह।
ओमेश

1
मुझे नहीं लगता कि सरणियों की आवश्यकता है। आप इसे आसानी से अस्थायी तालिकाओं UNION ALLका उपयोग करके या प्रक्रिया का उपयोग किए बिना कर सकते हैं।
ओमेश

28

MySql उदा के FIND_IN_SET () फ़ंक्शन का उपयोग करने का प्रयास करें

SET @c = 'xxx,yyy,zzz';

SELECT * from countries 
WHERE FIND_IN_SET(countryname,@c);

नोट: यदि आप CSV मानों के साथ पैरामीटर पास कर रहे हैं, तो आपको StoredProcedure में SET वेरिएबल नहीं करना होगा।


लंबाई सीमाओं से सावधान रहें, जो काफी कम हो सकती है: stackoverflow.com/q/2567000/1333493
निमो

18

आजकल JSON सरणी का उपयोग करना एक स्पष्ट जवाब होगा।

चूंकि यह एक पुराना लेकिन अभी भी प्रासंगिक प्रश्न है, इसलिए मैंने एक छोटा उदाहरण प्रस्तुत किया। JSON फ़ंक्शन mySQL 5.7.x / MariaDB 10.2.3 के बाद से उपलब्ध हैं

मैं ईएलटी () पर इस समाधान को पसंद करता हूं क्योंकि यह वास्तव में एक सरणी की तरह है और कोड में इस 'सरणी' का पुन: उपयोग किया जा सकता है।

लेकिन सावधान रहें: यह (JSON) निश्चित रूप से एक अस्थायी तालिका का उपयोग करने की तुलना में बहुत धीमा है। इसका और अधिक काम है। imo।

यहाँ एक JSON सरणी का उपयोग कैसे किया जाता है:

SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';

SELECT JSON_LENGTH(@myjson);
-- result: 19

SELECT JSON_VALUE(@myjson, '$[0]');
-- result: gmail.com

और यहाँ एक छोटा सा उदाहरण दिखाया गया है कि यह कैसे कार्य / प्रक्रिया में काम करता है:

DELIMITER //
CREATE OR REPLACE FUNCTION example() RETURNS varchar(1000) DETERMINISTIC
BEGIN
  DECLARE _result varchar(1000) DEFAULT '';
  DECLARE _counter INT DEFAULT 0;
  DECLARE _value varchar(50);

  SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';

  WHILE _counter < JSON_LENGTH(@myjson) DO
    -- do whatever, e.g. add-up strings...
    SET _result = CONCAT(_result, _counter, '-', JSON_VALUE(@myjson, CONCAT('$[',_counter,']')), '#');

    SET _counter = _counter + 1;
  END WHILE;

  RETURN _result;
END //
DELIMITER ;

SELECT example();

क्या आप कह रहे हैं कि ELT धीमा है या JSON धीमा है?
काणागावेलु सुगुमार

2
@ कनगवेलु सुगुमार: लेखन के समय JSON निश्चित रूप से धीमा है। मैंने उत्तर को स्पष्ट करने के लिए संपादन किया।
SeparateReality

16

सरणियों के बारे में नहीं जानते हैं, लेकिन सामान्य वर्कर कॉलम में अल्पविराम से अलग सूचियों को संग्रहीत करने का एक तरीका है।

और जब आपको उस सूची में कुछ खोजने की आवश्यकता हो तो आप FIND_IN_SET () फ़ंक्शन का उपयोग कर सकते हैं ।


अगर मैं एक सेट में सबसेट खोजना चाहता हूं, तो क्या कोई रास्ता है?
अक्षय विश्नोई

माफ़ करना! मुझे यकीन नहीं है कि यह संभव है।
वर्महिट

आपके पास सबसे अच्छा समाधान है
केल्विन

7
DELIMITER $$
CREATE DEFINER=`mysqldb`@`%` PROCEDURE `abc`()
BEGIN
  BEGIN 
    set @value :='11,2,3,1,'; 
    WHILE (LOCATE(',', @value) > 0) DO
      SET @V_DESIGNATION = SUBSTRING(@value,1, LOCATE(',',@value)-1); 
      SET @value = SUBSTRING(@value, LOCATE(',',@value) + 1); 
      select @V_DESIGNATION;
    END WHILE;
  END;
END$$
DELIMITER ;

2
कृपया बताएं कि इस कोड का उपयोग कैसे किया जाना है और यह प्रश्न का उत्तर कैसे देता है।
ईनपोकलम

जैसा कि यहां आप सरल प्रक्रिया करते हैं जो उस विशेष स्ट्रिंग के एक तत्व को देता है जो कि ओरेकल में सरणी के रूप में काम करता है।
सागर गंगवाल

आकाशवाणी? यह सवाल ओरेकल के बारे में नहीं है। इसके अलावा, ऐसा लगता है कि आप किसी सरणी को प्रक्रिया के भीतर परिभाषित कर रहे हैं।
ईनपोकलम

कृपया सिंटेक्स की जाँच करें यह केवल mysql के लिए है
सागर गंगवाल

अंतिम अल्पविराम याद मत करो!
ईगल_ईए

4

मुझे पता है कि यह थोड़ी देर की प्रतिक्रिया है, लेकिन मुझे हाल ही में इसी तरह की समस्या को हल करना था और सोचा कि यह दूसरों के लिए उपयोगी हो सकता है।

पृष्ठभूमि

नीचे दी गई तालिका पर विचार करें, जिसे 'mytable' कहा जाता है:

शुरुआती तालिका

समस्या केवल नवीनतम 3 रिकॉर्ड रखने और किसी भी पुराने रिकॉर्ड को हटाने की थी, जिसका सिस्टमिड = 1 (अन्य सिस्टमिड मानों के साथ तालिका में कई अन्य रिकॉर्ड हो सकते हैं)

यह अच्छा होगा कि आप केवल कथन का उपयोग करके ऐसा कर सकते हैं

DELETE FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)

हालाँकि यह अभी MySQL में समर्थित नहीं है और यदि आप इसे आज़माते हैं तो आपको एक त्रुटि मिलेगी

...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'

तो एक वर्कअराउंड की आवश्यकता होती है, जिसके तहत वैरिएबल का उपयोग करके मानों की एक सरणी IN चयनकर्ता को दी जाती है। हालाँकि, चूँकि चर को एकल मान की आवश्यकता होती है, इसलिए मुझे एक सारणी का अनुकरण करना होगा । चाल को अल्पविराम से अलग की गई मानों (स्ट्रिंग) की सूची के रूप में बनाने के लिए है और इसे निम्नानुसार चर पर असाइन करना है

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);

@Myvar में संग्रहीत परिणाम है

5,6,7

अगला, FIND_IN_SET चयनकर्ता का उपयोग सिम्युलेटेड सरणी से चयन करने के लिए किया जाता है

SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);

संयुक्त अंतिम परिणाम इस प्रकार है:

SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
DELETE FROM mytable WHERE FIND_IN_SET(id,@myvar);

मुझे पता है कि यह एक बहुत विशिष्ट मामला है। हालाँकि, इसे किसी भी अन्य मामले के अनुरूप संशोधित किया जा सकता है, जहाँ किसी चर को मानों को संग्रहीत करने की आवश्यकता होती है।

मुझे आशा है की इससे मदद मिलेगी।


3

यदि आप साहचर्य सरणियाँ चाहते हैं तो शायद कॉलम (कुंजी, मान) के साथ एक अस्थायी मेमोरी टेबल बनाएं। स्मृति तालिका होने के निकट mysql में सरणियाँ होने के लिए निकटतम चीज है


उम्म, मुझे सहयोगी सरणियाँ नहीं चाहिए, बस सरणियाँ।
einpoklum

आप केवल एक कॉलम के साथ एक अस्थायी मेमोरी टेबल का उपयोग कर सकते हैं और फिर कर्सर का उपयोग करके मानों को लूप कर सकते हैं, जो कि सरणियों का उपयोग करने के लिए निकटतम चीज़ है और / के लिए / जबकि गैर-घोषणात्मक प्रोग्रामिंग भाषा में छोरों
Pavle Lekic

भाषा में वास्तव में यह सुविधा होती है, अर्थात, कोई भी वाक्यात्मक कारण नहीं है कि आप एक वैक्टर को एक चर में चयन करने में सक्षम नहीं होना चाहिए जैसे आप इसमें एक स्केलर का चयन करते हैं।
einpoklum

3

यहाँ है कि मैं यह कैसे किया।

सबसे पहले, मैंने एक फ़ंक्शन बनाया जो यह जांचता है कि अल्पविराम द्वारा अलग किए गए मानों की सूची में एक लॉन्ग / इंटेगर / जो कुछ भी मूल्य है:

CREATE DEFINER = 'root'@'localhost' FUNCTION `is_id_in_ids`(
        `strIDs` VARCHAR(255),
        `_id` BIGINT
    )
    RETURNS BIT(1)
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

  DECLARE strLen    INT DEFAULT 0;
  DECLARE subStrLen INT DEFAULT 0;
  DECLARE subs      VARCHAR(255);

  IF strIDs IS NULL THEN
    SET strIDs = '';
  END IF;

  do_this:
    LOOP
      SET strLen = LENGTH(strIDs);
      SET subs = SUBSTRING_INDEX(strIDs, ',', 1);

      if ( CAST(subs AS UNSIGNED) = _id ) THEN
        -- founded
        return(1);
      END IF;

      SET subStrLen = LENGTH(SUBSTRING_INDEX(strIDs, ',', 1));
      SET strIDs = MID(strIDs, subStrLen+2, strLen);

      IF strIDs = NULL or trim(strIds) = '' THEN
        LEAVE do_this;
      END IF;

  END LOOP do_this;

   -- not founded
  return(0);

END;

तो अब आप आईडी की अल्पविराम से अलग सूची में एक आईडी खोज सकते हैं, जैसे:

select `is_id_in_ids`('1001,1002,1003',1002);

और आप इस फ़ंक्शन का उपयोग WHERE क्लॉज़ के अंदर कर सकते हैं, जैसे:

SELECT * FROM table1 WHERE `is_id_in_ids`('1001,1002,1003',table1_id);

यह एकमात्र तरीका था जो मैंने "सरणी" पैरामीटर को एक प्रक्रिया में पास करने के लिए पाया।


2

क्या सरणियों की बात कुशल नहीं है? यदि आप केवल मूल्यों के माध्यम से पुनरावृत्ति कर रहे हैं, तो मुझे लगता है कि अस्थायी (या स्थायी) तालिका पर एक कर्सर अल्पविराम की मांग करने की तुलना में अधिक समझ में आता है, नहीं? क्लीनर भी। लुकअप "mysql DECLARE CURSOR"।

रैंडम एक्सेस के लिए एक अस्थायी टेबल को संख्यात्मक रूप से अनुक्रमित प्राथमिक कुंजी के साथ। दुर्भाग्य से आपको प्राप्त होने वाली सबसे तेज़ पहुँच एक हैश तालिका है, न कि सच्ची यादृच्छिक पहुँच।


यह एक टिप्पणी है, एक जवाब नहीं है। मैंने संकेत नहीं दिया कि मैं सरणी के साथ क्या करना चाहता हूं।
einpoklum

2

मुझे आश्चर्य है कि उत्तर में से कोई भी ELT / FIELD का उल्लेख नहीं करता है।

ELT / FIELD एक सरणी के समान ही काम करता है खासकर यदि आपके पास स्थैतिक डेटा है।

FIND_IN_SET भी समान काम करता है, लेकिन इसमें एक पूरक कार्य नहीं होता है, लेकिन यह काफी आसान है।

mysql> select elt(2,'AA','BB','CC');
+-----------------------+
| elt(2,'AA','BB','CC') |
+-----------------------+
| BB                    |
+-----------------------+
1 row in set (0.00 sec)

mysql> select field('BB','AA','BB','CC');
+----------------------------+
| field('BB','AA','BB','CC') |
+----------------------------+
|                          2 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select find_in_set('BB','AA,BB,CC');
+------------------------------+
| find_in_set('BB','AA,BB,CC') |
+------------------------------+
|                            2 |
+------------------------------+
1 row in set (0.00 sec)

mysql>  SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1);
+-----------------------------------------------------------+
| SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1) |
+-----------------------------------------------------------+
| BB                                                        |
+-----------------------------------------------------------+
1 row in set (0.01 sec)

1

मूल्यों की सूची के लिए यह ठीक काम करता है:

SET @myArrayOfValue = '2,5,2,23,6,';

WHILE (LOCATE(',', @myArrayOfValue) > 0)
DO
SET @value = ELT(1, @myArrayOfValue);
    SET @STR = SUBSTRING(@myArrayOfValue, 1, LOCATE(',',@myArrayOfValue)-1);
    SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',', @myArrayOfValue) + 1);

    INSERT INTO `Demo` VALUES(@STR, 'hello');
END WHILE;

1

सेट का उपयोग करने वाले दोनों संस्करणों ने मेरे लिए काम नहीं किया (MySQL 5.5 के साथ परीक्षण किया गया)। फ़ंक्शन ELT () संपूर्ण सेट लौटाता है। WHILE स्टेटमेंट को ध्यान में रखते हुए केवल PROCEDURE के संदर्भ में मैं इसे अपने समाधान में जोड़ता हूं:

DROP PROCEDURE IF EXISTS __main__;

DELIMITER $
CREATE PROCEDURE __main__()
BEGIN
    SET @myArrayOfValue = '2,5,2,23,6,';

    WHILE (LOCATE(',', @myArrayOfValue) > 0)
    DO
        SET @value = LEFT(@myArrayOfValue, LOCATE(',',@myArrayOfValue) - 1);    
        SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);
    END WHILE;
END;
$
DELIMITER ;

CALL __main__;

सच कहूँ तो, मुझे नहीं लगता कि यह एक अच्छा अभ्यास है। यहां तक ​​कि अगर यह वास्तव में आवश्यक है, यह मुश्किल से पठनीय और काफी धीमी है।


1

उसी समस्या को देखने का एक और तरीका। आशा सहायक

DELIMITER $$
CREATE PROCEDURE ARR(v_value VARCHAR(100))
BEGIN

DECLARE v_tam VARCHAR(100);
DECLARE v_pos VARCHAR(100);

CREATE TEMPORARY TABLE IF NOT EXISTS split (split VARCHAR(50));

SET v_tam = (SELECT (LENGTH(v_value) - LENGTH(REPLACE(v_value,',',''))));
SET v_pos = 1;

WHILE (v_tam >= v_pos)
DO
    INSERT INTO split 
    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(v_value,',',v_pos),',', -1);
    SET v_pos = v_pos + 1;
END WHILE;

SELECT * FROM split;

DROP TEMPORARY TABLE split;

END$$


CALL ARR('1006212,1006404,1003404,1006505,444,');

वास्तव में, यह स्पष्ट नहीं है कि आप यहाँ क्या कह रहे हैं। 7 साल पहले के इस सवाल के कई प्रासंगिक जवाब हैं। अपना उत्तर निकालने या यह समझाने पर विचार करें कि आप एक उदाहरण के बजाय हमें सीधे / आम तौर पर बताने की कोशिश कर रहे हैं।
einpoklum

0

5.7.x के बाद MYSQL संस्करण में, आप सरणी को स्टोर करने के लिए JSON प्रकार का उपयोग कर सकते हैं। आप MYSQL के माध्यम से एक कुंजी द्वारा किसी सरणी का मान प्राप्त कर सकते हैं।


7
क्या आप इसका उदाहरण दे सकते हैं कि मैं यह कैसे करूंगा?
19p में einpoklum

0

फ़ंक्शन ELT (इंडेक्स नंबर, string1, string2, string3,…) से प्रेरित होकर, मुझे लगता है कि निम्नलिखित उदाहरण एक सरणी उदाहरण के रूप में काम करता है:

set @i := 1;
while @i <= 3
do
  insert into table(val) values (ELT(@i ,'val1','val2','val3'...));
set @i = @i + 1;
end while;

आशा है कि यह मदद करेगा।


0

यहाँ एक कॉमा सीमांकित स्ट्रिंग के माध्यम से लूपिंग के लिए MySQL के लिए एक उदाहरण है।

DECLARE v_delimited_string_access_index INT;
DECLARE v_delimited_string_access_value VARCHAR(255);
DECLARE v_can_still_find_values_in_delimited_string BOOLEAN;

SET v_can_still_find_values_in_delimited_string = true;
SET v_delimited_string_access_index = 0;
WHILE (v_can_still_find_values_in_delimited_string) DO
  SET v_delimited_string_access_value = get_from_delimiter_split_string(in_array, ',', v_delimited_string_access_index); -- get value from string
  SET v_delimited_string_access_index = v_delimited_string_access_index + 1;
  IF (v_delimited_string_access_value = '') THEN
    SET v_can_still_find_values_in_delimited_string = false; -- no value at this index, stop looping
  ELSE
    -- DO WHAT YOU WANT WITH v_delimited_string_access_value HERE
  END IF;
END WHILE;

यह get_from_delimiter_split_stringयहां परिभाषित फ़ंक्शन का उपयोग करता है: https://stackoverflow.com/a/59666211/3068233


अल्पविराम-सीमांकित तार पहले ही सुझाए गए हैं - वर्षों पहले।
ईनपोकलम

@einpoklum yep - और यहां उनके साथ बातचीत करने का एक और तरीका है
उलद कासच

0

एक सरणी चर वास्तव में आवश्यक है?

मैं पूछता हूं क्योंकि मैं मूल रूप से एक MySQL टेबल चर के रूप में एक सरणी जोड़ना चाहता था। मैं डेटाबेस डिजाइन के लिए अपेक्षाकृत नया था और यह सोचने की कोशिश कर रहा था कि एक विशिष्ट प्रोग्रामिंग भाषा फैशन में मैं इसे कैसे करूँगा।

लेकिन डेटाबेस अलग हैं। मैंने सोचा मुझे एक चर के रूप में एक सरणी चाहिए थी, लेकिन यह पता चला कि यह सिर्फ एक सामान्य MySQL डेटाबेस अभ्यास नहीं है।

मानक अभ्यास

सरणियों का वैकल्पिक समाधान एक अतिरिक्त तालिका जोड़ना है, और फिर अपनी मूल तालिका को एक विदेशी कुंजी के साथ संदर्भित करना है।

एक उदाहरण के रूप में, आइए एक ऐसे एप्लिकेशन की कल्पना करें जो स्टोर में खरीदना चाहता है जो हर व्यक्ति हर सामान पर नज़र रखता है।

मूल रूप से परिकल्पित तालिका बनाने की आज्ञा कुछ इस तरह दिखती थी:

#doesn't work
CREATE TABLE Person(
  name VARCHAR(50) PRIMARY KEY
  buy_list ARRAY
);

मुझे लगता है कि मैंने buy_list को आइटमों की अल्पविराम से अलग स्ट्रिंग या ऐसा कुछ होने की कल्पना की थी।

लेकिन MySQL के पास एक सरणी प्रकार फ़ील्ड नहीं है, इसलिए मुझे वास्तव में कुछ इस तरह की आवश्यकता थी:

CREATE TABLE Person(
  name VARCHAR(50) PRIMARY KEY
);
CREATE TABLE BuyList(
  person VARCHAR(50),
  item VARCHAR(50),
  PRIMARY KEY (person, item),
  CONSTRAINT fk_person FOREIGN KEY (person) REFERENCES Person(name)
);

यहाँ हम fk_person नामक बाधा को परिभाषित करते हैं। यह कहता है कि BuyList में 'व्यक्ति' क्षेत्र एक विदेशी कुंजी है। दूसरे शब्दों में, यह एक अन्य तालिका में एक प्राथमिक कुंजी है, विशेष रूप से व्यक्ति तालिका में 'नाम' फ़ील्ड, जो कि REFERENCE दर्शाती है।

हमने प्राथमिक कुंजी होने के लिए व्यक्ति और आइटम के संयोजन को भी परिभाषित किया, लेकिन तकनीकी रूप से यह आवश्यक नहीं है।

अंत में, यदि आप किसी व्यक्ति की सूची में सभी आइटम प्राप्त करना चाहते हैं, तो आप इस क्वेरी को चला सकते हैं:

SELECT item FROM BuyList WHERE person='John';

यह आपको जॉन की सूची में सभी आइटम देता है। कोई सरणियाँ आवश्यक!


मेरे द्वारा स्वीकृत समाधान है एक अस्थायी तालिका का उपयोग करने के लिए।
ईनपोकलम

बेशक। फिर मैंने अपने जैसे किसी भी व्यक्ति के लिए इस उत्तर को शामिल किया, जो इस पेज पर एक सरणी प्रकार बनाने का तरीका ढूंढ रहा है - जो शुरू में यह नहीं समझ पाए कि सरणियाँ MySQL में एक प्रकार क्यों नहीं हैं। यह डिजाइन से ऐसा लगता है। सामान्य मामले का यहां प्रतिनिधित्व नहीं किया गया था इसलिए मैंने इसमें शामिल किया कि मैंने दूसरों को यह समझने के लिए सीखा कि सरणियों की आमतौर पर आवश्यकता नहीं होती है। मुझे उम्मीद नहीं है कि आप मेरे जवाब का चयन करेंगे। यह उपयोग के मामले पर निर्भर करता है। आपके पास एक विशिष्ट उपयोग के मामले के लिए अपना स्वीकृत जवाब है और मैं इस उत्तर को सामान्य उपयोग के मामले के लिए प्रदान कर रहा हूं।
क्राफ्टीदेविल

0

अगर हमारे पास एक जैसा टेबल है

mysql> select * from user_mail;
+------------+-------+
| email      | user | 
+------------+-------+-
| email1@gmail |     1 | 
| email2@gmail |     2 |
+------------+-------+--------+------------+

और सारणी तालिका:

mysql> select * from user_mail_array;
+------------+-------+-------------+
| email      | user | preferences |
+------------+-------+-------------+
| email1@gmail |     1 |           1 |
| email1@gmail |     1 |           2 |
| email1@gmail |     1 |           3 |
| email1@gmail |     1 |           4 |
| email2@gmail |     2 |           5 |
| email2@gmail |     2 |           6 |

हम CONCAT फ़ंक्शन के साथ एक सरणी के रूप में दूसरी तालिका की पंक्तियों का चयन कर सकते हैं:

mysql> SELECT t1.*, GROUP_CONCAT(t2.preferences) AS preferences
     FROM user_mail t1,user_mail_array t2
       where t1.email=t2.email and t1.user=t2.user
     GROUP BY t1.email,t1.user;

+------------+-------+--------+------------+-------------+
| email      | user | preferences |
+------------+-------+--------+------------+-------------+
|email1@gmail |     1 | 1,3,2,4     |
|email2@gmail |     2 | 5,6         |
+------------+-------+--------+------------+-------------+

मुझे लगता है कि क्लिंटन के जवाब की नकल।
ईनपोकलम

-2

मुझे लगता है कि मैं इस उत्तर पर सुधार कर सकता हूं। इसे इस्तेमाल करे:

'प्रैंक' पैरामीटर एक सीएसवी है। अर्थात। '1,2,3,4 ..... आदि'

CREATE PROCEDURE AddRanks(
IN Pranks TEXT
)
BEGIN
  DECLARE VCounter INTEGER;
  DECLARE VStringToAdd VARCHAR(50);
  SET VCounter = 0;
  START TRANSACTION;
  REPEAT
    SET VStringToAdd = (SELECT TRIM(SUBSTRING_INDEX(Pranks, ',', 1)));
    SET Pranks = (SELECT RIGHT(Pranks, TRIM(LENGTH(Pranks) - LENGTH(SUBSTRING_INDEX(Pranks, ',', 1))-1)));
    INSERT INTO tbl_rank_names(rank)
    VALUES(VStringToAdd);
    SET VCounter = VCounter + 1;
  UNTIL (Pranks = '')
  END REPEAT;
  SELECT VCounter AS 'Records added';
  COMMIT;
END;

यह विधि CSV मूल्यों की खोज की गई स्ट्रिंग को लूप के प्रत्येक पुनरावृत्ति के साथ उत्तरोत्तर कम करती है, जो मुझे लगता है कि अनुकूलन के लिए बेहतर होगा।


'यह उत्तर' क्या है जिसका आप उल्लेख कर रहे हैं? इसके अलावा, आपके पास CSV फ़ाइल नहीं है।
einpoklum

मैं CSV फ़ाइल का संदर्भ नहीं दे रहा था, मैं CSV मान का उल्लेख कर रहा था जैसे '1,2,3,4 ... आदि'
user2288580

-2

मैं कई संग्रहों के लिए कुछ इस तरह की कोशिश करेंगे। मैं एक MySQL शुरुआत कर रहा हूँ। फ़ंक्शन नामों के बारे में क्षमा करें, यह तय नहीं कर सका कि कौन से नाम सबसे अच्छे होंगे।

delimiter //

drop  procedure init_
//
create procedure init_()
begin
  CREATE TEMPORARY TABLE if not exists 
    val_store(  
    realm  varchar(30) 
    ,  id  varchar(30) 
    ,  val   varchar(255) 
    ,  primary key ( realm , id )
    );
end;
//

drop function if exists get_
//
create function get_( p_realm varchar(30) , p_id varchar(30) )
  returns varchar(255)
  reads sql data
begin 
  declare ret_val varchar(255);
  declare continue handler for 1146 set ret_val = null;
  select val into ret_val from val_store where id = p_id;
  return ret_val;
end;
//

drop procedure if exists set_
//
create procedure set_( p_realm varchar(30) , p_id varchar(30) , p_val varchar(255) )
begin
  call init_(); 
  insert into val_store (realm,id,val) values (p_realm , p_id , p_val) on duplicate key update val = p_val;
end;
//

drop   procedure if exists remove_
//
create procedure remove_( p_realm varchar(30) , p_id varchar(30) )
begin
  call init_();
  delete from val_store where realm = p_realm and id = p_id;
end;
//

drop   procedure if exists erase_
//
create procedure erase_( p_realm varchar(30) ) 
begin
  call init_();
  delete from val_store where realm = p_realm;
end;
//

call set_('my_array_table_name','my_key','my_value');

select get_('my_array_table_name','my_key');

मुझे लगता है कि मैं समझता हूं कि आप क्या सुझाव दे रहे हैं, लेकिन यह काफी स्पष्ट है और शायद अविश्वसनीय रूप से धीमा ...
21

मैं तनाव परीक्षण के बिना इसे समर्थन या खारिज नहीं कर सकता। यह मूल रूप से एक अस्थायी टेबल (या सामान्य टेबल) पर एक प्राथमिक कुंजी लुकअप और सम्मिलन है। मैं इसका उपयोग तब तक करूंगा जब तक कि मैं समस्याओं में नहीं भागता या एक बेहतर तरीका नहीं खोजता; लेकिन मैं पूरी तरह से Oracle PL / SQL में कम्पाइलर और गेम लिखने जैसी अजीब चीजें करता हूं।
डेव

-2

डेटा को एक सरणी या एक पंक्ति के रूप में सहेजने के बजाय केवल आपको प्राप्त हर मूल्य के लिए अलग-अलग पंक्तियाँ बनानी चाहिए। यह सभी को एक साथ रखने के बजाय समझने में बहुत आसान बना देगा।


कृपया इसे कैसे साझा करें
निको हेस

-5

क्या आपने PHP के क्रमांकन () का उपयोग करने की कोशिश की है? यह आपको एक चर की सामग्री को स्ट्रिंग में स्टोर करने की अनुमति देता है पीएचपी समझता है और डेटाबेस के लिए सुरक्षित है (यह मानते हुए कि आप इसे पहले भाग चुके हैं)।

$array = array(
    1 => 'some data',
    2 => 'some more'
);

//Assuming you're already connected to the database
$sql = sprintf("INSERT INTO `yourTable` (`rowID`, `rowContent`) VALUES (NULL, '%s')"
     ,  serialize(mysql_real_escape_string($array, $dbConnection)));
mysql_query($sql, $dbConnection) or die(mysql_error());

आप बिना क्रमांकित सारणी के भी सटीक कार्य कर सकते हैं

$array2 = array(
    'something' => 'something else'
);

या

$array3 = array(
    'somethingNew'
);

7
मैं PHP के साथ काम नहीं कर रहा हूं, इसलिए यह मेरे लिए वास्तव में प्रासंगिक नहीं है।
ईनपोकलम

1
क्रमबद्ध के बजाय JSON का उपयोग करें। यह अधिक सामान्य और भाषा-स्वतंत्र है।
रिक जेम्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.