একটি এসকিউএল IN () ধারাটিতে মানগুলির ক্রম অনুসারে ক্রম


154

আমি ভাবছি যে কোনও আইএন () ধারাতে মানগুলির ক্রম অনুসারে অর্ডার করার জন্য (সম্ভবত আরও ভালতর উপায়) আছে কিনা।

সমস্যাটি হ'ল আমার কাছে 2 টি ক্যোয়ারী রয়েছে, এটির মধ্যে একটি আইডি পেয়ে যায় এবং দ্বিতীয়টি সমস্ত তথ্য পুনরুদ্ধার করে। প্রথমটি আইডিগুলির ক্রম তৈরি করে যা আমি দ্বিতীয় দ্বারা আদেশ করতে চাই। আইডিগুলি সঠিক ক্রমে একটি আইএন () ধারাতে রাখা হয়।

সুতরাং এটি এমন কিছু হবে (অত্যন্ত সরলীকৃত):

SELECT id FROM table1 WHERE ... ORDER BY display_order, name

SELECT name, description, ... WHERE id IN ([id's from first])

ইস্যুটি হ'ল দ্বিতীয় ক্যোয়ারী একই ক্রমে ফলাফলগুলি ফিরিয়ে দেয় না যে আইডিগুলি আইএন () ধারাটিতে রাখা হয়।

একটি সমাধান আমি খুঁজে পেয়েছি হ'ল সমস্ত আইডি একটি অটো ইনক্রিমেন্টিং ফিল্ডের সাথে একটি টেম্প টেবিলের মধ্যে রাখা যা পরে দ্বিতীয় ক্যোয়ারিতে যোগ হয়।

একটি ভালো বিকল্প আছে কি?

দ্রষ্টব্য: যেহেতু প্রথম ক্যোয়ারীটি "ব্যবহারকারীর দ্বারা" চালানো হয় এবং দ্বিতীয়টি একটি ব্যাকগ্রাউন্ড প্রক্রিয়াতে চালিত হয় তাই সাব-কোয়েরিগুলি ব্যবহার করে 2 কে 1 টি প্রশ্নের সাথে একত্রিত করার উপায় নেই।

আমি মাইএসকিউএল ব্যবহার করছি, তবে আমি ভাবছি যে এটি অন্যান্য ডিবিগুলির জন্য কী কী বিকল্প রয়েছে তা উল্লেখ করা কার্যকর হতে পারে।

উত্তর:


186

মাইএসকিউএল এর FIELD()ফাংশন ব্যবহার করুন :

SELECT name, description, ...
FROM ...
WHERE id IN([ids, any order])
ORDER BY FIELD(id, [ids in order])

FIELD() প্রথম প্যারামিটারের সমান যে প্রথম প্যারামিটারের সূচকটি ফিরে আসবে (নিজেই প্রথম প্যারামিটার বাদে)।

FIELD('a', 'a', 'b', 'c')

ফিরে আসবে 1

FIELD('a', 'c', 'b', 'a')

3 ফিরে আসবে

আপনি একই ক্রমে আইডিকে IN()ক্লজ এবং FIELD()ফাংশনে পেস্ট করলে এটি আপনি যা করতে চান ঠিক তা করবে ।


3
@ ভোজটো একটি স্বেচ্ছাসেবী অর্ডার অনুসারে বাছাই সংজ্ঞা দ্বারা ধীর। এই আছে যেহেতু কোন গ্যারান্টি যে তার ভাল আছে INএবং FIELDপরামিতি সমান। প্রোগ্রামের কোডে এটি করা অতিরিক্ত অতিরিক্ত জ্ঞান ব্যবহার করে দ্রুত হতে পারে। অবশ্যই, যদি আপনার সার্ভারের পারফরম্যান্স মাথায় থাকে তবে সার্ভারের চেয়ে ক্লায়েন্টের উপর এই বোঝা চাপানো বুদ্ধিমানের কাজ হতে পারে।
ivan_pozdeev

1
কি sqlite?
fnc12

15

সাজানো ডেটা কীভাবে পাবেন তা অনুসরণ করুন following

SELECT ...
  FROM ...
 WHERE zip IN (91709,92886,92807,...,91356)
   AND user.status=1
ORDER 
    BY provider.package_id DESC 
     , FIELD(zip,91709,92886,92807,...,91356)
LIMIT 10

11

দুটি সমাধান যা মনে মনে বসন্ত:

  1. order by case id when 123 then 1 when 456 then 2 else null end asc

  2. order by instr(','||id||',',',123,456,') asc

( instr()ওরাকল কাছ থেকেই আসে; হয়তো আপনি locate()বা charindex()বা ওই জাতীয় কিছু)


মাইএসকিউএল-এর জন্য, FIELD_IN_SET () এছাড়াও ব্যবহার করা যেতে পারে: dev.mysql.com/doc/refman/5.0/en/…
ড্যারিল হেইন


6

আপনি যদি এমএস এসকিউএল সার্ভার ২০০++ এ ক্যোয়ারী দ্বারা ইনপুট করা মানগুলি ব্যবহার করে কোনও ক্যোয়ারিতে স্বেচ্ছাসেবী বাছাই করতে চান তবে এটি ফ্লাইতে একটি টেবিল তৈরি করে এবং এর মতো একটি সংযুক্তি (ওপি থেকে নাম ব্যবহার করে) করা যেতে পারে।

SELECT table1.name, table1.description ... 
FROM (VALUES (id1,1), (id2,2), (id3,3) ...) AS orderTbl(orderKey, orderIdx) 
LEFT JOIN table1 ON orderTbl.orderKey=table1.id
ORDER BY orderTbl.orderIdx

আপনি যদি একই জিনিসটি করে তবে অন্যটি, তবে এএনএসআই এসকিউএলে ভ্যালুয়াস স্টেটমেন্টটি প্রতিস্থাপন করেন, তবে এটি কোনও এসকিউএল ডাটাবেসে কাজ করা উচিত।

দ্রষ্টব্য: সারণীর দ্বিতীয় কলামটি (অর্ডারটিবিএল.অর্ডারআইডিএক্স) প্রয়োজনীয় যখন 100 বা তার চেয়ে বড় রেকর্ড সেট করে। আমার কাছে প্রথমে অর্ডারআইডিএক্স কলাম নেই, তবে আমি দেখতে পেয়েছি যে ফলাফলের 100 টিরও বেশি বড় সেটগুলির সাথে আমাকে সেই কলামটি স্পষ্টভাবে বাছাই করতে হয়েছিল; এসকিউএল সার্ভার এক্সপ্রেস 2014 যাইহোক।


এই প্রশ্নটি মাইএসকিউএল সম্পর্কিত ... আপনার ক্যোয়ারী মাইএসকিউএলে কাজ করবে তা নিশ্চিত নয়।
ড্যারিল হেইন

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

মনে রাখবেন, এই আমার জন্য কাজ, কিন্তু পরে আমি উল্লেখ প্রতিস্থাপিত orderTbl.orderKey, orderTbl.orderIndexদ্বারা orderKey,orderIndex
পিটার

5
SELECT ORDER_NO, DELIVERY_ADDRESS 
from IFSAPP.PURCHASE_ORDER_TAB 
where ORDER_NO in ('52000077','52000079','52000167','52000297','52000204','52000409','52000126') 
ORDER BY instr('52000077,52000079,52000167,52000297,52000204,52000409,52000126',ORDER_NO)

সত্যিই দুর্দান্ত কাজ করেছে


ওরাকলে আমার জন্য কাজ করেছেন। দ্রুত এবং সহজ। ধন্যবাদ।
মেনাচেম

4

আইএন ক্লজ মানগুলির একটি সেট বর্ণনা করে এবং সেটে অর্ডার থাকে না।

আপনার যোগদানের সাথে সমাধান এবং তারপরে display_orderকলামে অর্ডার দেওয়া সর্বাধিক সঠিক সমাধান; অন্য যে কোনও কিছু সম্ভবত ডিবিএমএস-নির্দিষ্ট হ্যাক (বা স্ট্যান্ডার্ড এসকিউএল-তে ওএলএপ ফাংশন সহ কিছু স্টাফ করছে)। অবশ্যই, যোগদানটি সর্বাধিক প্রায় বহনযোগ্য সমাধান (যদিও display_orderমানগুলির সাথে ডেটা তৈরি করা সমস্যাযুক্ত হতে পারে)। নোট করুন যে আপনি ক্রম কলামগুলি নির্বাচন করার প্রয়োজন হতে পারে; এটি স্ট্যান্ডার্ড এসকিউএল-তে প্রয়োজনীয়তা ছিল, যদিও আমি বিশ্বাস করি এটি একটি নিয়ম হিসাবে কিছুক্ষণ আগে (সম্ভবত এসকিউএল -২৯ হিসাবে অনেক আগে) শিথিল হয়েছিল।


2

ওরাকল-এর জন্য, ইন্সটার () ফাংশন ব্যবহার করে জন-এর সমাধান কাজ করে। এখানে সামান্য ভিন্ন সমাধান যা কাজ করেছে - SELECT id FROM table1 WHERE id IN (1, 20, 45, 60) ORDER BY instr('1, 20, 45, 60', id)



2

আমি কেবল এটির চেষ্টা করেছি এমএস এসকিউএল সার্ভার যেখানে আমাদের ফিল্ড () নেই:

SELECT table1.id
... 
INNER JOIN
    (VALUES (10,1),(3,2),(4,3),(5,4),(7,5),(8,6),(9,7),(2,8),(6,9),(5,10)
    ) AS X(id,sortorder)
        ON X.id = table1.id
    ORDER BY X.sortorder

নোট করুন যে আমিও নকল করতে দিচ্ছি।


1

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

সুতরাং এটি সম্পর্কে:

  1. ইউজার ইন্টারফেস বিট রান করে এবং আপনার তৈরি করা একটি নতুন টেবিলের মধ্যে মান সন্নিবেশ করে। এটি আইডি, অবস্থান এবং কিছু ধরণের কাজের নম্বর শনাক্তকারী প্রবেশ করানো হবে)
  2. কাজের নম্বরটি পটভূমি প্রক্রিয়াতে (সমস্ত আইডির পরিবর্তে) পাস করা হয়েছে
  3. পটভূমি প্রক্রিয়াটি প্রথম ধাপে টেবিল থেকে একটি নির্বাচন করে এবং আপনার প্রয়োজনীয় অন্যান্য তথ্য পেতে আপনি এতে যোগদান করেন। এটি অবস্থানের কলাম অনুসারে WHOLE ক্লজ এবং অর্ডারগুলিতে কাজের নম্বর ব্যবহার করে।
  4. ব্যাকগ্রাউন্ড প্রক্রিয়াটি শেষ হয়ে গেলে, কাজ শনাক্তকরণের ভিত্তিতে সারণী থেকে মুছে ফেলা হয়।

1

আমি মনে করি আপনার ডেটা এমনভাবে সংরক্ষণ করার ব্যবস্থা করা উচিত যাতে আপনি সহজভাবে একটি যোগদান করবেন এবং এটি নিখুঁত হবে, তাই কোনও হ্যাক এবং জটিল জিনিস চলছে না।

আমি উদাহরণস্বরূপ এসকিউএলাইটে ট্র্যাক আইডির একটি "সাম্প্রতিক সময়ে চালিত" তালিকার তালিকাটি করেছি যা আমি কেবল করি:

SELECT * FROM recently NATURAL JOIN tracks;

1
ওহ, আমার ইচ্ছা যদি জীবনটি এত সহজ হত :)
ড্যারিল হেইন

0

এটি একটি শট দিন:

SELECT name, description, ...
WHERE id IN
    (SELECT id FROM table1 WHERE...)
ORDER BY
    (SELECT display_order FROM table1 WHERE...),
    (SELECT name FROM table1 WHERE...)

পারস্পরিক সহযোগিত সাবকিউরিয়াসগুলি সঠিকভাবে কাজ করতে ডাব্লুএইচআরই সম্ভবত সম্ভবত কিছুটা টুইট করবে aking তবে মূল নীতিটি যথাযথ হওয়া উচিত।


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