একটি নির্বাচন subquery থেকে একাধিক কলাম পান


24
SELECT 
   *, 
   p.name AS name, 
   p.image, 
   p.price,
   ( 
       SELECT ps.price 
       FROM product_special ps 
       WHERE p.id = ps.id
         AND ps.date < NOW() 
       ORDER BY ps.priority ASC, LIMIT 1
   ) AS special_price,
   ( 
       SELECT ps.date 
       FROM product_special ps 
       WHERE p.id = ps.id
         AND ps.date < NOW() 
       ORDER BY ps.priority ASC, LIMIT 1
   ) AS date
FROM product p LEFT JOIN product_special ps ON (p.id = ps.id)

আপনি দেখতে পাচ্ছেন যে ঠিক একই কৌনিকটি পুনরাবৃত্তি করছি কেবল অন্য কলামটি বের করার জন্য। আমি ভাবছি এই কাজ করার আরও ভাল উপায় আছে?

আইডি হ'ল উভয় টেবিলের প্রাথমিক কী। প্রোডাক্ট_স্পেশাল.প্রিয়রিটি অনন্য করতে আমার কোনও সমস্যা নেই যদি এটি সহায়তা করতে পারে।

উত্তর:


11

ধরে নেওয়া সংমিশ্রণটি product_special.id, product_special.priorityঅনন্য

 SELECT p.*, special_price,special_date
 FROM product p
 LEFT JOIN 
 (
     SELECT ps.id, ps.price as special_price, ps.`date` as special_date
     FROM product_special ps
     INNER JOIN 
     (
       SELECT id, MIN(priority) as min_priority 
       FROM product_special
       GROUP BY id
     ) ps2 
     ON (ps2.id = ps.id)
 )a ON (a.id=p.id)

5

যদি না আপনি ক্ষেত্রগুলিকে বিশেষ_প্রাইস.প্রাইস এবং তারিখ হিসাবে তারিখ হিসাবে প্রত্যাবর্তন করতে চান তবে সাবকোয়ারির ভিতরে নাম কেন রাখবেন না? যেমন

SELECT p.*, p.name AS  name, p.image, p.price, ps.*
FROM product p
LEFT JOIN
   (SELECT
      psi.price as special_price, psi.date as my_date 
    FROM product_special psi
    WHERE 
      p.id = psi.id AND
      psi.date < NOW()
    ORDER BY psi.priority ASC, LIMIT 1
   ) AS ps ON
  p.id = ps.id

আপনার ক্যোয়ারী ভাষার একটি FIRST () সমষ্টিগত ফাংশন আছে? নিশ্চিত না আপনি যদি প্রোডাক্ট_সেসিফিকের পিকে আইডি এবং অগ্রাধিকারের (উভয় এএসসি বাছাই) মধ্যে সংমিশ্রণ করতে পারেন এবং অর্ডার ধারাটি এতে পরিবর্তন করতে পারেনGROUP BY id, psi.priority

আপনি পুরোপুরি আদেশটি পুরোপুরি মুছে ফেলতে এবং ব্যবহার করতে পারবেন HAVING MIN(psi.priority)


2

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

left join highestPriorityProductSpecial(p.id) on true

ঠিক আছে, কিন্তু না

left join (select * from product_special ps where ps.id = p.id order by priority desc limit 1) on true

যদিও ফাংশনটির সংজ্ঞাটি যথাযথভাবে এটি।

সুতরাং, এটি আসলে একটি সহজ সমাধান (কমপক্ষে 9.1 এ): ফাংশনের অভ্যন্তরে সীমাবদ্ধতা করে আপনার সর্বোচ্চ অগ্রাধিকার সারিটি বের করার জন্য একটি ফাংশন তৈরি করুন।

তবে ফাংশনগুলির মধ্যে একটি অসুবিধা রয়েছে যে ক্যোয়ারী পরিকল্পনাগুলি তাদের ভিতরে কী চলছে তা প্রদর্শন করবে না এবং আমি বিশ্বাস করি যে এটি সর্বদা নেস্টেড লুপের যোগদানটি বেছে নেবে, এমনকি এটি সর্বোত্তম নাও হতে পারে।


6
cross apply হয় (2013 সালে মুক্তি) 9.3 দিয়ে শুরু Postgres পাওয়া কিন্তু তারা এসকিউএল মান মেনে চলে এবং স্ট্যান্ডার্ড ব্যবহার করতে lateralঅপারেটর। আপনার দ্বিতীয় ক্যোয়ারীতে প্রতিস্থাপন left joinসঙ্গেleft join lateral
a_horse_with_no_name

2

নিম্নলিখিত এসকিউএল আদেশটি ব্যবহার করে দেখুন:

SELECT p.name,p.image,p.price,pss.price,pss.date
FROM Product p OUTER APPLY(SELECT TOP(1)* 
FROM ProductSpecial ps
WHERE p.Id = ps.Id ORDER BY ps.priority )as pss

1
আপনি দয়া করে আপনার উত্তরে আরও তথ্য যুক্ত করতে পারেন
আহমদ আবুহস্না

LIMITপ্রশ্নযুক্ত কোডটি ডিবিএমএসের সাথে ব্যবহার করে এবং ট্যাগ হয় না (সুতরাং এটি মাইএসকিউএল বা পোস্টগ্রিস বা এসকিউএলাইট বা সম্ভবত অন্য কোনও ডিবিএম হতে পারে)। উত্তরের কোডটি ব্যবহার করে OUTER APPLYএবং TOPতাই এটি কেবলমাত্র এসকিউএল সার্ভারে (এবং সিবাসে) কাজ করবে যা নেই LIMIT
ypercubeᵀᴹ

এইটি স্কেল সার্ভারের জন্য কেবলমাত্র অন্যান্য ডাটাবেসের ক্ষেত্রে প্রযোজ্য যা আমরা নির্বাচনী বিবৃতিতে অভ্যন্তরীণ কোয়েরিটি ব্যবহার করতে পারি।
সন্তোষ অ্যাপানা

Postgres সেখানে নয় OUTER APPLY, কিন্তু আছে পার্শ্বীয় , যা সমতুল্য হওয়া উচিত। একটি উদাহরণ এটি ব্যবহার: stackoverflow.com/a/47926042/4850646
লুকাস Basquerotto

2

ডেজোর উত্তরটি দিয়ে অনুপ্রাণিত /dba//a/222471/127433 আমি পোস্টগ্র্রেএসকিউএল এ অ্যারে ব্যবহার করে সমস্যাটি সমাধান করছি:

SELECT 
   *, 
   p.name AS name, 
   p.image, 
   p.price,
   ( 
       SELECT ARRAY[ps.price, ps.date]
       FROM product_special ps 
       WHERE p.id = ps.id
         AND ps.date < NOW() 
       ORDER BY ps.priority ASC, LIMIT 1
   ) AS special_price_and_date
FROM product p LEFT JOIN product_special ps ON (p.id = ps.id)

স্বীকারযোগ্যভাবে এটি এখনও মাত্র একটি কলাম, তবে আমার কোডে আমি দুটি মান সহজেই অ্যাক্সেস করতে পারি। আশা করি এটি আপনার পক্ষেও কাজ করে।


1

আমি কেবল এখানে সর্বশেষ অবলম্বনের জন্য এখানে রাখতে চাই, যারা ডাটাবেস ইঞ্জিন ব্যবহার করেন এমন প্রত্যেকের জন্য যা অন্য এক বা একাধিক উত্তর সমর্থন করে না ...

আপনি এর মতো কিছু ব্যবহার করতে পারেন:

SELECT (col1 || col2) as col3 

(পৃথককারী সহ, বা নির্দিষ্ট দৈর্ঘ্যে কল 1 এবং কল 2 ফর্ম্যাট করে)) পরে সাব-স্ট্রিংগুলি ব্যবহার করে আপনার ডেটা আঁকুন।

আমি আশা করি যে কেউ এটি দরকারী হবে।


0

জেড / ওএসের জন্য ডিবি 2-এ, সাব-সাবকেলে একাধিক কলামগুলি ফেরত দিতে ব্যবহার packএবং unpackফাংশন ব্যবহার করুন ।

SELECT 
   *, 
   p.name AS name, 
   p.image, 
   p.price,
    unpack((select PACK (CCSID 1028,
               ps.price,
               ps.date)
         FROM product_special ps 
       WHERE p.id = ps.id
         AND ps.date < NOW() 
       ORDER BY ps.priority ASC, LIMIT 1)) .* AS (SPECIAL_PRICE double, DATE date)
FROM product p LEFT JOIN product_special ps ON (p.id = ps.id);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.