आप mysql से हर n-th पंक्ति का चयन कैसे करते हैं


79

मेरे पास एक डेटाबेस में मूल्यों की एक श्रृंखला है जिसे मुझे लाइन चार्ट बनाने के लिए खींचने की आवश्यकता है। क्योंकि मुझे उच्च रिज़ॉल्यूशन की आवश्यकता नहीं है, मैं डेटाबेस से प्रत्येक 5 वीं पंक्ति का चयन करके डेटा को फिर से भरना चाहूंगा।

जवाबों:


84
SELECT * 
FROM ( 
    SELECT 
        @row := @row +1 AS rownum, [column name] 
    FROM ( 
        SELECT @row :=0) r, [table name] 
    ) ranked 
WHERE rownum % [n] = 1 

5
क्या कोई इस बारे में अधिक जानकारी प्रदान कर सकता है कि यह कैसे काम करता है? उदाहरण के लिए प्रत्येक 5 वीं पंक्ति में पूछे गए प्रश्न और उत्तर में 5 का कोई उल्लेख नहीं है।
Crazometer

4
@Crazometer [n]5 वीं पंक्ति में प्रत्येक 5 वीं पंक्ति को प्राप्त करने के लिए क्वेरी से प्रतिस्थापित करें ।
बेंजामिन मानस ने

इस पर विस्तार करने के लिए, क्या होगा यदि आप पहली पंक्ति के साथ शुरू नहीं करना चाहते हैं लेकिन उदाहरण के लिए दूसरा?
HPWD

आप की जगह लेंगे @HPWD @row :=0साथ@row :=2
Binar वेब

@BinarWeb नहीं, तुम बदल जाएगा = 1करने के लिए= 2
ysth

55

आप पंक्तियों को प्राप्त करने के लिए mod 5 का प्रयास कर सकते हैं जहाँ ID 5 से अधिक है (मान लें कि आपके पास क्रमबद्ध ID आईडी का कुछ प्रकार है।)

select * from table where table.id mod 5 = 0;

19
यह भी मान लें कि आपके पास डिलीट या रोलबैक के कारण अनुक्रम में कोई अंतराल नहीं है।
बिल कार्विन

3
यह अधिकांश भाग के लिए काम करेगा लेकिन हटाए गए पंक्तियों के लिए नहीं है।
कॉर्बन ब्रूक

2
कुछ परीक्षण के लिए सरल और शानदार :-)
रिकार्ड लीलबर्गबर्ग

1
यह समझ में आता है कि क्या आपका चयन सभी डेटा को पुनः प्राप्त करता है। यदि आपके पास अपने चयन में अतिरिक्त मानदंड हैं, तो यह कहना मुश्किल होगा कि कौन सा डेटा (यदि कोई है) इसे पुनर्प्राप्त करेगा।
j_kubik

24

चूंकि आपने कहा था कि आप MySQL का उपयोग कर रहे हैं, आप एक सतत पंक्ति क्रमांकन बनाने के लिए उपयोगकर्ता चर का उपयोग कर सकते हैं । हालांकि आपको इसे एक व्युत्पन्न तालिका (उपश्रेणी) में रखना होगा।

SET @x := 0;
SELECT *
FROM (SELECT (@x:=@x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t
WHERE x MOD 5 = 0;

मैंने ORDER BY RAND()एक छद्म आयामी नमूना प्राप्त करने के लिए जोड़ा , बजाय हर बार नमूने में अनियंत्रित तालिका की हर पांचवीं पंक्ति की अनुमति देने के लिए।


एक अनाम उपयोगकर्ता ने इसे बदलने के x MOD 5 = 0लिए इसे संपादित करने का प्रयास किया x MOD 5 = 1। मैंने इसे अपने मूल में बदल दिया है।

रिकॉर्ड के लिए, कोई भी उस स्थिति में 0 और 4 के बीच किसी भी मूल्य का उपयोग कर सकता है, और किसी भी अन्य पर एक मूल्य पसंद करने का कोई कारण नहीं है।


मैं इस पर अपना जवाब अपडेट कर रहा था, और आपने मुझे इसे हरा दिया! अच्छी सोच।
जोश स्टोडोला

1
दुर्भाग्य से, यह कई प्रविष्टियों के साथ काम करते समय कम से कम x100 द्वारा निष्पादन को धीमा कर देता है
फिल्प

10
SET @a = 0;
SELECT * FROM t where (@a := @a + 1) % 2 = 0;

यह एक अनियंत्रित, पंक्तियों के समानांतर प्रसंस्करण के लिए केवल-पढ़ने के लिए तालिका के विभाजन के लिए बहुत अच्छा काम करता है, और वाक्यविन्यास पढ़ना और समझना आसान है। आपको बस प्रत्येक पंक्ति को केवल एक बार वापस करने के लिए प्राथमिक कुंजी कॉलम पर ORDER BY जोड़ना होगा।
हम्बड्स

2

मैं कुछ इस तरह की तलाश में था। टेलर और बिल के जवाब ने मुझे उनके विचारों में सुधार करने के लिए प्रेरित किया।

तालिका data1 में फ़ील्ड्स_डेट है, मान जिसे हम प्रत्येक 2d रिकॉर्ड का चयन करना चाहते हैं एक क्वेरी से सीमित एक read_date रेंज द्वारा व्युत्पन्न तालिका का नाम मनमाना है और यहां डीटी कहा जाता है

प्रश्न:

 SET @row := 0;
  SELECT * FROM  ( SELECT @row := @row +1 AS rownum, read_date, value  FROM data1  
  WHERE  read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0

धन्यवाद, मैं इसके लिए देख रहा था। मुझे किसी तरह जांचने की जरूरत है कि क्या संग्रहीत प्रक्रियाओं के लिए लॉग टेबल में एक निश्चित कॉलम का मूल्य हर दूसरी बार समान था। जैसे 'proc start', 'proc end'। सब कुछ ठीक होने पर नीचे दिए गए sql का परिणाम 1 होगा। SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime > now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
14

1

आप इस क्वेरी का उपयोग कर सकते हैं,

set @n=2; <!-- nth row -->
select * from (SELECT t.*, 
       @rowid := @rowid + 1 AS ID
  FROM TABLE t, 
       (SELECT @rowid := 0) dummy) A where A.ID mod @n = 0;

या आप n को अपने nth मान से बदल सकते हैं


1
SELECT *
FROM ( 
    SELECT @row := @row +1 AS rownum, posts.*
    FROM (
        SELECT @row :=0) r, posts
    ) ranked
WHERE rownum %3 = 1

जहाँ पोस्ट मेरी मेज है


1

यदि आप MariaDB 10.2, MySQL 8 या उसके बाद का उपयोग कर रहे हैं, तो आप यह अधिक दक्षता से कर सकते हैं, और मैं सामान्य टेबल एक्सप्रेशंस और विंडो फ़ंक्शंस का उपयोग करके अधिक स्पष्ट रूप से सोचता हूं ।

WITH ordering AS (
  SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.* 
    FROM example ORDER BY name
)
SELECT * FROM ordering WHERE MOD(n, 5) = 0;

वैचारिक रूप से, यह क्षेत्र exampleद्वारा आदेशित तालिका की सामग्री के साथ एक अस्थायी तालिका बनाता है name, एक अतिरिक्त फ़ील्ड को जोड़ता nहै जिसे पंक्ति संख्या कहा जाता है, और फिर केवल उन पंक्तियों को संख्याओं के साथ लाया जाता है जो 5 वीं, यानी प्रत्येक 5 वीं पंक्ति से बिल्कुल विभाज्य होती हैं। व्यवहार में, डेटाबेस इंजन अक्सर इससे बेहतर अनुकूलन करने में सक्षम होता है। लेकिन यहां तक ​​कि अगर यह इसे और अधिक अनुकूलित नहीं करता है, तो मुझे लगता है कि उपयोगकर्ता चर का उपयोग करने की तुलना में यह स्पष्ट है जैसा कि आपको MySQL के पुराने संस्करणों में था।


0

यदि आपको परिणाम सेट में पंक्ति संख्या की आवश्यकता नहीं है तो आप क्वेरी को सरल बना सकते हैं।

SELECT 
    [column name] 
FROM
    (SELECT @row:=0) temp, 
    [table name] 
WHERE (@row:=@row + 1) % [n] = 1 

निम्नलिखित प्लेसहोल्डर बदलें:

  1. बदलने के [column name]उन स्तंभों की सूची से जिन्हें आपको लाने की आवश्यकता है।
  2. बदलने के [table name]अपनी तालिका के नाम से ।
  3. [n]एक नंबर से बदलें । जैसे अगर आपको हर 5 वीं पंक्ति की आवश्यकता है, तो इसे 5 से बदलें

धन्यवाद, यह करीब है, लेकिन आप ऐसा करने से बेहतर हैं: से नाम चुनें (SELECT @row: = - 1) अस्थायी, टी जहां (@row: = @ पंक्ति + 1)% 1 = 0; इसके दो फायदे हैं। पहला, n की परवाह किए बिना, आपको हमेशा पहली पंक्ति मिलती है और दूसरी, यदि आप n = 1 बनाते हैं, तो आपको सभी मान प्राप्त होते हैं, बजाय कोई नहीं। (दो बदलाव: पंक्ति में -1: = - 1 और n = 0 के बजाय n = 1)
ब्रूस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.