মাইএসকিউএল "গ্রুপ বাই" এবং "অর্ডার বাই"


98

আমি ইমেইলগুলির একটি টেবিল থেকে সারিগুলির একটি গুচ্ছ নির্বাচন করতে এবং প্রেরকের কাছ থেকে তাদের গোষ্ঠী করতে সক্ষম হতে চাই। আমার ক্যোয়ারীটি এমন দেখাচ্ছে:

SELECT 
    `timestamp`, `fromEmail`, `subject`
FROM `incomingEmails` 
GROUP BY LOWER(`fromEmail`) 
ORDER BY `timestamp` DESC

ক্যোয়ারী প্রায়শই আমার যেমনটি ইচ্ছা তেমন কাজ করে - এটি ইমেল দ্বারা গোষ্ঠীভুক্ত রেকর্ডগুলি নির্বাচন করে। সমস্যাটি হ'ল বিষয় এবং টাইমস্ট্যাম্প কোনও নির্দিষ্ট ই-মেইল ঠিকানার সাম্প্রতিকতম রেকর্ডের সাথে সামঞ্জস্য করে না।

উদাহরণস্বরূপ, এটি ফিরে আসতে পারে:

fromEmail: john@example.com, subject: hello
fromEmail: mark@example.com, subject: welcome

ডাটাবেসে রেকর্ডগুলি যখন:

fromEmail: john@example.com, subject: hello
fromEmail: john@example.com, subject: programming question
fromEmail: mark@example.com, subject: welcome

যদি "প্রোগ্রামিং প্রশ্ন" বিষয়টি সর্বাধিক সাম্প্রতিক হয় তবে আমি কীভাবে ইমেলগুলি গোষ্ঠীভুক্ত করার সময় সেই রেকর্ডটি নির্বাচন করতে মাইএসকিউএল পেতে পারি?

উত্তর:


142

একটি সহজ সমাধান হ'ল প্রথমে অর্ডার স্টেটমেন্টের সাহায্যে কোয়েরিটি গুটিয়ে রাখা এবং পরে গ্রুপ প্রয়োগ করা :

SELECT * FROM ( 
    SELECT `timestamp`, `fromEmail`, `subject`
    FROM `incomingEmails` 
    ORDER BY `timestamp` DESC
) AS tmp_table GROUP BY LOWER(`fromEmail`)

এটি যোগটি ব্যবহার করার মতো তবে এটি দেখতে খুব সুন্দর দেখাচ্ছে।

একটি গ্রুপে একটি গ্রুপের মাধ্যমে একটি বিভাগে অ-সমষ্টিগত কলামগুলি ব্যবহার করা মানহীন। মাইএসকিউএল সাধারণত খুঁজে পাওয়া প্রথম সারির মানগুলি ফিরিয়ে দেয় এবং বাকীটি ফেলে দেয়। যে কোনও অর্ডার বাই শর্তাদি কেবল প্রত্যাবর্তিত কলাম মানের জন্য প্রযোজ্য, বাতিল হওয়াগুলিতে নয়।

গুরুত্বপূর্ণ আপডেট আপডেটে অভ্যাসে কাজ করার জন্য অ-সমষ্টিগত কলামগুলি নির্বাচন করা হয়েছে তবে তার উপর নির্ভর করা উচিত নয়। প্রতি মাইএসকিউএল ডকুমেন্টেশন "এই দরকারী। প্রাথমিকভাবে যখন একদল নাম প্রতিটি nonaggregated কলামে সব মান প্রতি দলের জন্য একই সার্ভার কোনো মান পছন্দ করে নিন বিনামূল্যে প্রতিটি গ্রুপ থেকে, তাই যদি না তারা একই, মান নির্বাচিতরা অনির্দিষ্ট হয় "

5..7.৫ হিসাবে কেবলমাত্র ওয়ানওয়াই_এফএলএল_আগ্রো_বিওয়াই ডিফল্টরূপে সক্ষম হয়েছে সুতরাং অ-সমষ্টিযুক্ত কলামগুলি ক্যোয়ারী ত্রুটির কারণ ঘটায় (ER_WRONG_FIELD_WITH_GROUP)

@ মাইকেপটি সমাধানের নীচে উল্লেখ করে যেহেতু 5.7 বা তদুর্ধ্ব থেকে ANY_VALUE () ব্যবহার করা

দেখুন http://www.cafewebmaster.com/mysql-order-sort-group https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html HTTPS: //dev.mysql .com / ডক / রেফম্যান / 5.7 / এন / গ্রুপ-বাই হ্যান্ডলিং html https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-function.html#function_any-value


7
আমি কয়েক বছর আগে একই সমাধান নিয়ে এসেছি এবং এটির দুর্দান্ত সমাধান। কুডো টু বি 7 কিচ। দুটি বিষয় এখানে যদিও ... গ্রুপ বাই কেস সংবেদনশীল, তাই লোয়ার () অপ্রয়োজনীয়, এবং দ্বিতীয়ত, $ ইউজারআইডি পিএইচপি থেকে সরাসরি পরিবর্তনশীল হিসাবে উপস্থিত হয়, আপনার কোডটি এসএইচএল ইঞ্জেকশন ঝুঁকিপূর্ণ হতে পারে যদি $ ইউজারআইডি ব্যবহারকারীর সরবরাহ করা হয় এবং বাধ্য না করা হয় একটি পূর্ণসংখ্যা হতে।
ভেলক্রো


4
As of 5.7.5 ONLY_FULL_GROUP_BY is enabled by default, i.e. it's impossible to use non-aggregate columns.এসএমএল মোডটি অ্যাডমিন সুবিধা ছাড়াই রানটাইম চলাকালীন পরিবর্তিত হতে পারে, সুতরাং এটি কেবলমাত্র ওএনএলওয়াই_ফুলল_গ্রোপ_বিআই অক্ষম করা খুব সহজ। উদাহরণস্বরূপ: SET SESSION sql_mode = '';। ডেমো: db-food.com/f/esww483qFQXbXzJmkHZ8VT/3
মাইকেপ

4
অথবা কেবলমাত্র বাইপাসকে সক্ষম করা কেবলমাত্র ONLY_FULL_GROUP_BY এ্যানওয়াই_ভ্যালু () ব্যবহার করা। আরও দেখুন dev.mysql.com/doc/refman/8.0/en/…
মাইকেপ

এই উত্তরটি ভুল
মার্ক

44

এখানে একটি পদ্ধতির:

SELECT cur.textID, cur.fromEmail, cur.subject, 
     cur.timestamp, cur.read
FROM incomingEmails cur
LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.timestamp < next.timestamp
WHERE next.timestamp is null
and cur.toUserID = '$userID' 
ORDER BY LOWER(cur.fromEmail)

মূলত, আপনি নিজেরাই টেবিলটিতে যোগ দিন, পরবর্তী সারিগুলি অনুসন্ধান করে। যে ধারাটিতে আপনি উল্লেখ করেছেন যে পরে সারিগুলি থাকতে পারে না। এটি আপনাকে সর্বশেষতম সারি দেয়।

যদি একই টাইমস্ট্যাম্পের সাথে একাধিক ইমেল থাকতে পারে তবে এই ক্যোয়ারির পরিশোধন প্রয়োজন। ইমেল টেবিলটিতে যদি একটি ইনক্রিমেন্টাল আইডি কলাম থাকে তবে জোয়িনের মতো পরিবর্তন করুন:

LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.id < next.id

বলেছিল যে textIDঅস্পষ্ট ছিল = /
জন কুর্লাক

4
তারপরে অস্পষ্টতা অপসারণ করুন এবং এটি cur.textID এর মতো সারণির নামের সাথে উপসর্গ করুন। উত্তরেও পরিবর্তন হয়েছে।
আন্দোমার

এটিই একমাত্র সমাধান যা ডক্ট্রিন ডিকিউএল দিয়ে করা সম্ভব।
ভিজিওন

আপনি একাধিক কলামের জন্য এত ভালভাবে যোগদান করার চেষ্টা করলে এটি কার্যকর হয় না। IE আপনি যখন সর্বশেষতম ইমেল এবং সর্বশেষ ব্যবহারকারীর নাম সন্ধান করার চেষ্টা করছেন এবং আপনার একক ক্যোয়ারিতে এই ক্রিয়াকলাপটি সম্পাদন করতে একাধিক স্ব-বাম যোগদান করতে হবে।
লাভেন ডায়াল

অতীত এবং ভবিষ্যতের টাইমস্ট্যাম্প / তারিখগুলির সাথে কাজ করার সময়, ফলাফলটি ভবিষ্যতের অ-ভবিষ্যতের তারিখগুলিতে সীমাবদ্ধ করতে, আপনাকে LEFT JOINমানদণ্ডে আরও একটি শর্ত যুক্ত করতে AND next.timestamp <= UNIX_TIMESTAMP()
হবে

34

ইতিমধ্যে একটি উত্তরে যেমন উল্লেখ করা হয়েছে, বর্তমান উত্তরটি ভুল, কারণ গ্রুপ বাই নির্বিচারে উইন্ডো থেকে রেকর্ড নির্বাচন করে।

যদি কেউ মাইএসকিউএল 5.6, বা মাইএসকিউএল 5.7 ব্যবহার করে থাকে ONLY_FULL_GROUP_BYতবে সঠিক (নির্জনবাদী) কোয়েরিটি হ'ল:

SELECT incomingEmails.*
  FROM (
    SELECT fromEmail, MAX(timestamp) `timestamp`
    FROM incomingEmails
    GROUP BY fromEmail
  ) filtered_incomingEmails
  JOIN incomingEmails USING (fromEmail, timestamp)
GROUP BY fromEmail, timestamp

কোয়েরিটি দক্ষতার সাথে চালানোর জন্য, যথাযথ ইনডেক্সিং প্রয়োজন।

দ্রষ্টব্য যে সরলকরণের উদ্দেশ্যে, আমি সরিয়েছি LOWER(), যা বেশিরভাগ ক্ষেত্রে ব্যবহার করা হবে না।


4
এটি সঠিক উত্তর হওয়া উচিত। আমি স্রেফ এটি সম্পর্কিত আমার ওয়েবসাইটে একটি বাগ আবিষ্কার করেছি। order byঅন্যান্য উত্তর subselect মধ্যে সবকিছু কোনো প্রভাব নেই।
জেটে

4
ওএমজি, দয়া করে এটি গ্রহণযোগ্য উত্তর করুন। গৃহীত একজনটি আমার সময়টির 5 ঘন্টা নষ্ট করে :(
রিচার্ড কার্সি

29

এইভাবে গ্রুপের মাধ্যমে আপনার ক্যোয়ারীটি গুটিয়ে রাখার মাধ্যমে অর্ডার করার পরে একটি গ্রুপ করুন:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.from

4
সুতরাং GROUP BY` স্বয়ংক্রিয়ভাবে সর্বশেষতম time, বা নতুন time, বা এলোমেলোভাবে নির্বাচন করে ?
xrDDDD

4
এটি নতুন সময়টি নির্বাচন করে কারণ আমরা আদেশ করছি time DESCএবং তারপরে গোষ্ঠীটি প্রথমটি গ্রহণ করে (সর্বশেষ)।
11101101b

এখন কেবলমাত্র আমি মাইএসকিএল 5.1-এ ভিউউজে সাব-সিলেক্টে যোগ দিতে পারতাম। সম্ভবত সেই বৈশিষ্ট্যটি একটি নতুন প্রকাশে আসে in
IcarusNM

22

এসকিউএল স্ট্যান্ডার্ড অনুযায়ী আপনি নির্বাচিত তালিকায় অ-সমষ্টি কলামগুলি ব্যবহার করতে পারবেন না। মাইএসকিউএল এই জাতীয় ব্যবহারের অনুমতি দেয় (কেবলমাত্র কেবলমাত্র ওএনএলএইফএলএল_আরগ্রুপ_বিওয়াই মোড ব্যবহার করা হয়েছে) তবে ফলাফল অনুমানযোগ্য নয়।

কেবলমাত্র_ফুল্ল_জিগ্রুপ_বিওয়াই

আপনার প্রথমে ইমেল, এমআইএন (পঠিত) এবং তারপরে দ্বিতীয় কোয়েরি (বা সাবকোয়ারি) - বিষয় সহ নির্বাচন করা উচিত।


এমআইএন (পঠিত) "পঠন" এর সর্বনিম্ন মানটি ফিরিয়ে দেয়। পরিবর্তে তিনি সম্ভবত সর্বশেষতম ইমেলের "পঠন" পতাকাটি সন্ধান করছেন।
আন্দোমার

2

আমি প্রদর্শিত উভয় চেয়ে জটিল জটিল প্রশ্নের জন্য এই উভয় পদ্ধতির সাথে লড়াই করেছি, কারণ আমি যে সূচকগুলি রেখেছি তা সাব-কোয়ের পদ্ধতিটি মারাত্মকভাবে অদক্ষ ছিল এবং কারণ আমি হাইবারনেটের মাধ্যমে বাইরের স্ব-যোগদান করতে পারিনি

এটি করার সর্বোত্তম (এবং সহজতম) উপায় হ'ল এমন কিছু দ্বারা গোষ্ঠীভূত করা যা আপনার প্রয়োজনীয় ক্ষেত্রগুলিকে একত্রীকরণের জন্য তৈরি করা হয়েছে এবং তারপরে নির্বাচন বিভাগে অভিব্যক্তি ব্যবহার করে সেগুলি টেনে আনা। আপনার যদি একটি ম্যাক্স () প্রয়োজন হয় তা নিশ্চিত করুন যে আপনি যে ক্ষেত্রটি MAX () করতে চান তা সর্বদা কনকেনটেটেড সত্তার সর্বাধিক উল্লেখযোগ্য প্রান্তে রয়েছে।

এটি বোঝার মূল চাবিকাঠিটি হ'ল ক্যোয়ারিটি কেবল তখনই বোধগম্য হতে পারে যদি এই অন্যান্য ক্ষেত্রগুলি কোনও সত্তার জন্য সর্বোচ্চ () সঞ্চার করে যা ম্যাক্সকে সন্তুষ্ট করে), সুতরাং সাজানোর ক্ষেত্রে শর্তাবলীর অন্যান্য অংশগুলি উপেক্ষা করা যেতে পারে। এটি এই লিঙ্কের একেবারে নীচে কীভাবে এটি করবেন তা ব্যাখ্যা করে। http://dev.mysql.com/doc/refman/5.0/en/group-by-hided-columns.html

আপনি যদি ক্ষেত্রগুলির সূচনা করতে পারেন এমন ক্ষেত্রগুলির সংমিশ্রণটির প্রাক-গণনা করতে যদি আপনি প্রবেশ সন্নিবেশ / আপডেট ইভেন্ট (ট্রিগারের মতো) পেতে পারেন এবং ক্যোয়ারীটি তত দ্রুত হবে যেন গোষ্ঠীটি কেবলমাত্র ক্ষেত্রের উপরে গিয়েছিল যা আপনি ম্যাক্স করতে চেয়েছিলেন ( )। এমনকি সর্বাধিক একাধিক ক্ষেত্র পেতে আপনি এটি ব্যবহার করতে পারেন। আমি নেস্টেড সেট হিসাবে প্রকাশিত বহুমাত্রিক গাছের বিরুদ্ধে অনুসন্ধান করতে এটি ব্যবহার করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.