2009-09-03 7 views
9

का उपयोग कर एक मेज मैं MySQL में एक मेज है जो निम्न स्तंभ हैं के साथ काम कर रहा हूँ से (एक बयान में) एकाधिक स्तंभों के लिए मूल्य मिलान: तालिका मेंएक MySQL

id, january, february, march, april, etc 

डेटा इस तरह दिखता है:

aa, 0, 0, 1, 0 
ab, 1, 0, 1, 0 
ac, 1, 1, 0, 0 
ad, 1, 1, 1, 0 

क्वेरी के लिए, मैं आसानी से कर सकता है:

select * from table where january = 1 and february = 1 

परिणाम होगा:

ac, 1, 1, 0, 0 
ad, 1, 1, 1, 0 

मैं वहाँ इस तरह यह करने के लिए कोई तरीका है जानना चाहता हूँ:

select * from table where table.columns = 1 

मैं वास्तव में नाम मैन्युअल रूप से निर्दिष्ट करने (उन्हें बाहर टाइपिंग) के बिना अभिव्यक्ति में तालिका स्तंभ का उपयोग करना चाहते।

बोनस (+1) प्रश्न:
इसे इस तरह मिलान/के खिलाफ का उपयोग किया जा सकता है:

select * from table 
where 
(
    match (somehow,get,the,table,columns,I,need,here) 
    against (1 in boolean mode) 
) 

अपना समय के लिए धन्यवाद! :)

+0

"WHERE table.colmuns = 1" खंड में आप वास्तव में क्या परीक्षण करते हैं? क्या आप रिकॉर्ड चाहते हैं जहां वास्तव में जनवरी, फरवरी आदि में से एक है? – Martijn

+0

मैं उन सभी पंक्तियों को प्राप्त करना चाहता हूं जिनमें तालिका के किसी भी स्तंभ में 1 शामिल है। –

उत्तर

4

आप एक तैयार वक्तव्य उपयोग करने के लिए, आप क्या करना चाहते हैं केवल गतिशील एसक्यूएल के साथ किया जा सकता है, क्योंकि है:

SET @stmt = 'SELECT * FROM YOUR_TABLE WHERE 1 = 1 ' 
SET @stmt = CONCAT(@stmt, (SELECT CONCAT_WS(' AND ', CONCAT(column_name, ' = 1 ')) 
          FROM INFORMATION_SCHEMA.COLUMNS 
          WHERE table_name = 'YOUR_TABLE' 
          AND table_schema = 'db_name' 
          AND column_name NOT IN ('id'))); 

PREPARE stmt FROM @stmt; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

पहला सेट बयान एक बुनियादी SELECT कथन निर्माण करती है; "1 = 1" भाग "AND column = 1"

दूसरा एसईटी स्टेटमेंट तालिका के नाम के आधार पर कॉलम की सूची प्राप्त करने के लिए क्वेरी की सामग्री को समेकित करने के लिए क्वेरी की सामग्री को समेकित करने के लिए आसान है। पहले एसईटी कथन में स्ट्रिंग।

SELECT CONCAT_WS(' AND ', CONCAT(column_name, ' = 1 ')) 
    FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_name = 'YOUR_TABLE' 
    AND table_schema = 'db_name' 
    AND column_name NOT IN ('id') 

... एक पंक्ति है कि जैसा दिखता है "AND january = 1 AND february = 1 ..." वापस आ जाएगी: विचार है कि यह है। यदि आप अन्य कॉलम हैं जो WHERE क्लॉज में नहीं चाहते हैं तो आपको इन क्लॉज को अपडेट करना होगा।

शेष मानक तैयार कथन सामग्री है, और यह सब एक संग्रहीत प्रक्रिया के भीतर होना होगा।

+0

मुझे लगता है कि ओपी 'AND' के बजाय' OR' चाहता है। अगर किसी अन्य स्कीमा में एक ही नाम की एक तालिका है, तो जानकारी स्कीमा में 'schema_name' को भी देखना न भूलें। –

+0

@ बिल: Thx, स्कीमा नाम के लिए लापता चेक जोड़ा गया। क्या आप 'OR' का उपयोग करने के बारे में निश्चित हैं? ओपी स्पष्ट रूप से "जनवरी = 1 और फरवरी = 1" कहता है। –

0

आप MySQL में वैक्टर का उपयोग कर सकते हैं:

select * from table where (january, february) = (1, 1) 

पाठ स्तंभ के लिए अलग सर्वर और ग्राहक collations से सावधान रहें, संभवतः आप स्पष्ट रूप से तो मिलान का उल्लेख करना होगा।

+0

यह वह नहीं है जिसे मैं ढूंढ रहा हूं, मैं कॉलम नाम निर्दिष्ट नहीं करना चाहता हूं। अच्छी अवधारणा हालांकि, वैक्टर उपयोगी हैं। –

+0

तब बहुत स्पष्ट नहीं है। आप वास्तव में नाम निर्दिष्ट किए बिना अभिव्यक्ति में टेबल कॉलम का उपयोग करना चाहते हैं? हो सकता है कि आप तालिका मेटाडेटा प्राप्त करने के लिए पहले 'DESCRIBE तालिका' निष्पादित करें और फिर बाद के प्रश्नों में फ़ील्ड का उपयोग करें? – pingw33n

+0

प्रश्न अद्यतन किया गया। उम्मीद है कि यह अब स्पष्ट है :) –

0

मेरी राय में यह खराब टेबल डिज़ाइन जैसा प्रतीत होता है (मुझे लगता है कि यह केवल आपकी समस्या का एक उदाहरण है, लेकिन मेरे साथ सहन करें, और मुझे लगता है कि इस अवधारणा को बेहतर तरीके से मॉडल किया जा सकता है।
यहां

Things  Things_Months  Months 
    thing_id  thing_id   Month_id 
    thing_info  month_id   Month_Name 
        thing_month_id  order_field 

और यहाँ एसक्यूएल होगा:: टेबल हैं

select thing_info, month_name 
    from things, things_months, months 
    where things.thing_id = things_months.thing_id 
    and things_months.month_id = months.month_id 
    order by things.things_info, months.order_field 

परिणाम होगा

thingy 1, January 
    thingy 1, February 
    thingy 2, April 
    thingy 3, November 
    thingy 3, December 
+0

जय, आप सही हैं, यह खराब टेबल डिज़ाइन की वजह से है। हालांकि मुझे टेबल संरचना को बदलने की अनुमति नहीं है। –

0
select * from table where 1 in (january, february) 
+0

नहीं, यह या तो नहीं है। फिर भी सुझाव के लिए धन्यवाद। –

1

मैं समझता हूं कि श्रीमान स्मिथ क्या करने की कोशिश कर रहा है।

यह 12 पंक्तियों x 4 कॉलम बनाम 1 पंक्ति x 12 कॉलम का प्रश्न है।

आईडी, किसी की आईडी, महीने, मूल्य x 12 प्रति माह

1, 101, january, 1 
2, 101, february, 1 
3, 101, march, 0 
etc.. 

इस के लिए इसी एसक्यूएल बयान होगा::

पूर्व तालिका डिजाइन की तरह कुछ होगा

$sqlQuery = "SELECT month FROM my_month_table WHERE value = 1"; 

मैं क्या अनुमान लगा रहा हूं श्रीमान।स्मिथ कोशिश कर रहा है:

आईडी, किसी की आईडी, जनवरी, फरवरी, मार्च ...

$sqlQuery = "SELECT corrensponding_column_names_to_where_clause FROM my_month_table WHERE column_value = 1"; 
1

आप मिलान का उपयोग यह कर सकते हैं ... के खिलाफ।

उस स्थिति में आपकी तालिका MyISAM तालिका होनी चाहिए और आपको आवश्यक कॉलम सहित FULLTEXT अनुक्रमणिका बनाना होगा।

0

एक दृश्य के साथ समस्या को हल करने के बारे में कैसे? डेटा

CREATE TABLE `d001ab05`.`months` (
`id` INT NOT NULL , 
`jan` BOOL NOT NULL , 
`feb` BOOL NOT NULL , 
`mar` BOOL NOT NULL , 
`apr` BOOL NOT NULL , 
`may` BOOL NOT NULL , 
`jun` BOOL NOT NULL , 
`jul` BOOL NOT NULL , 
`aug` BOOL NOT NULL , 
`sep` BOOL NOT NULL , 
`oct` BOOL NOT NULL , 
`nov` BOOL NOT NULL , 
`dec` BOOL NOT NULL , 
PRIMARY KEY (`id`) 
) ENGINE = InnoDB; 

सम्मिलित: चयन युक्त

INSERT INTO `d001ab05`.`months` (
`id`, `jan`, `feb`, `mar`, `apr`, `may`, `jun`, 
`jul`, `aug`, `sep`, `oct`, `nov`, `dec` 
) VALUES (
'1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' 
), (
'2', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' 
), (
'3', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' 
), (
'4', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' 
); 

दृश्य:

CREATE OR REPLACE VIEW `moncase` AS 
SELECT id, 
CASE WHEN `jan` =1 OR `feb` =1 OR `mar` =1 OR `apr` =1 OR `may` =1 OR 
`jun` =1 OR `jul` =1 OR `aug` =1 OR `sep` =1 OR `oct` =1 OR `nov` =1 OR `dec` =1 
THEN 1 ELSE 0 END AS or_over_months 
FROM months; 

चुनें:

SELECT * FROM `moncase` WHERE `or_over_months` = 1; 

परिणाम:

id | or_over_months 
1 | 1 
2 | 1 
4 | 1 
1

कोशिश दृश्य

CREATE VIEW v_months 
AS 
SELECT *, CONCAT(CAST(jan AS CHAR(1)), 
        CAST(feb AS CHAR(1)), 
        CAST(mar AS CHAR(1)), 
        ...) AS all 
FROM months 

बनाने के लिए आप कुछ इस तरह मिल जाएगा:

aa, 0, 0, 1, 0, 0010 
ab, 1, 0, 1, 0, 1010 
ac, 1, 1, 0, 0, 1100 
ad, 1, 1, 1, 0, 1110 

और फिर आप

SELECT * FROM v_months WHERE all = '100110010101' 

क्वेरी कर सकता है या यदि आप क्वेरी चाहते हैं "सभी पंक्तियां प्राप्त , जहां feb = 1 ", आप इस तरह लिख सकते हैं:

SELECT * FROM v_months WHERE all LIKE '_1____________'  

जहां '_' बिल्कुल एक चरित्र से मेल खाता है।

+0

अपने परिणामों पर फ़ंक्शन और फ़िल्टरिंग का उपयोग प्रदर्शन के लिए एक आपदा होगी। डेटाबेस को तालिका में सभी पंक्तियों के लिए फ़ंक्शन का मूल्यांकन करना होगा, और उसके बाद उस स्ट्रिंग के आउटपुट की तुलना करें जिसके साथ आप मेल खाते हैं। कार्यों के आउटपुट का उपयोग, या तो प्रत्यक्ष या परोक्ष रूप से, एक क्वेरी अनुमानित (WHERE क्लॉज) प्रदर्शन के लिए सामान्य नो-नो है। – dcrosta

0

आपको जो चाहिए वह एक गैर-पिवट ऑपरेशन है। माइक्रोसॉफ्ट एसक्यूएल सर्वर मानक एसक्यूएल के एक्सटेंशन के रूप में PIVOT और UNPIVOT का समर्थन करता है। मुझे आरडीबीएमएस के किसी अन्य ब्रांड के बारे में पता नहीं है जो अंतर्निर्मित पिवट/अनपॉट कार्यक्षमता का समर्थन करता है। निश्चित रूप से MySQL इसका समर्थन नहीं करता है।

आप क्योंकि डॉक्स say के रूप में इस मामले में FULLTEXT खोज का उपयोग नहीं कर सकते,:

पूर्ण-पाठ अनुक्रमणिका केवल MyISAM तालिकाओं के साथ इस्तेमाल किया जा सकता है, और चार, VARCHAR, या के लिए ही बनाया जा सकता है टेक्स्ट कॉलम

और यह क्योंकि MATCH() विधेय आप की प्रतिलिपि प्राप्त सूचकांक में सभी कॉलम सूची की जरूरत कॉलम वैसे भी निर्दिष्ट करने के लिए, की आवश्यकता होगी, से आप को राहत देने नहीं होता।

यदि आप सभी 12 महीनों को एन्कोड करने के लिए पंक्ति-प्रति-माह या एकल कॉलम स्टोर करने के लिए तालिका को पुन: स्थापित नहीं कर सकते हैं, तो आपको गतिशील SQL उत्पन्न करने की आवश्यकता है।