এসকিউএল-তে আপনি কীভাবে রেঞ্জগুলিতে "দলবদ্ধ" হতে পারেন?


181

ধরুন আমার কাছে একটি সংখ্যার কলামযুক্ত একটি টেবিল রয়েছে (এটিকে "স্কোর" বলতে দিন)।

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

উদাহরণ স্বরূপ:

স্কোর পরিসর | সংঘটন সংখ্যা
-------------------------------------
   0-9 | 11
  10-19 | 14
  20-29 | 3
   ... | ...

এই উদাহরণে 0 থেকে 9 এর পরিসরে স্কোর সহ 11 টি সারি ছিল, 10 থেকে 19 এর পরিসরে স্কোর সহ 14 টি সারি এবং 20-29 পরিসরের স্কোর সহ 3 সারি।

এটি সেট আপ করার কোন সহজ উপায় আছে? আপনি কি সুপারিশ করেন?

উত্তর:


143

সর্বোচ্চ ভোট দেওয়া উত্তরগুলির মধ্যে দুটিও এসকিউএল সার্ভার 2000-এ সঠিক নয় Perhaps সম্ভবত তারা একটি ভিন্ন সংস্করণ ব্যবহার করছিল।

এসকিউএল সার্ভার 2000 এ উভয়ের সঠিক সংস্করণ এখানে।

select t.range as [score range], count(*) as [number of occurences]
from (
  select case  
    when score between 0 and 9 then ' 0- 9'
    when score between 10 and 19 then '10-19'
    else '20-99' end as range
  from scores) t
group by t.range

অথবা

select t.range as [score range], count(*) as [number of occurences]
from (
      select user_id,
         case when score >= 0 and score< 10 then '0-9'
         when score >= 10 and score< 20 then '10-19'
         else '20-99' end as range
     from scores) t
group by t.range

আমি কি আর একটি কলাম একসাথে করতে পারি (গ্রুপ গণনা মত) বলুন যে আমি প্রতিটি স্কোর ব্যাপ্তির জন্য বৃত্তি কলামকে একত্রিত করতে চাই। আমি চেষ্টা করেছিলাম, তবে তা
ঠিকভাবে

চমৎকার উত্তর @ রন টফিন, তবে আপনার যখন 10-20, 100-200 এর মতো দুটি রেঞ্জ থাকে, তখন আদেশটি কার্যকর হয় না। আপনার যদি 10-20, 100-200,20-30 ইত্যাদি অর্ডার থাকে তবে অর্ডারটির জন্য কোনও টিপস?
জো 5

2
@ জোহাস এটি কিছুটা হ্যাক তবে এটি কাজ করে: লেন দ্বারা আদেশ করুন (t.range), t.range
রন


1
আপনার যদি এখনও বাক্যবিন্যাসের সমস্যা থাকে তবে এই উত্তরটি দেখুন: dba.stackexchange.com/questions/22491/…
রবার্ট হোসিং

33

বিকল্প পদ্ধতির মধ্যে কোয়েরিতে এম্বেড করার পরিবর্তে কোনও সারণীতে রেঞ্জগুলি সংরক্ষণ করা জড়িত। আপনি একটি টেবিল দিয়ে শেষ করবেন, এটিকে রেঞ্জগুলি বলবেন, এটি দেখতে এই রকম দেখাচ্ছে:

LowerLimit   UpperLimit   Range 
0              9          '0-9'
10            19          '10-19'
20            29          '20-29'
30            39          '30-39'

এবং একটি কোয়েরি যা দেখতে দেখতে:

Select
   Range as [Score Range],
   Count(*) as [Number of Occurences]
from
   Ranges r inner join Scores s on s.Score between r.LowerLimit and r.UpperLimit
group by Range

এর অর্থ একটি সারণী স্থাপন করা নয়, তবে যখন পছন্দসই ব্যাপ্তি পরিবর্তন হয় এটি বজায় রাখা সহজ হবে। কোন কোড পরিবর্তন প্রয়োজন!


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

31

আমি এখানে উত্তরগুলি দেখতে পাচ্ছি যা এসকিউএল সার্ভারের সিনট্যাক্সে কাজ করবে না। আমি ব্যবহার করব:

select t.range as [score range], count(*) as [number of occurences]
from (
  select case 
    when score between  0 and  9 then ' 0-9 '
    when score between 10 and 19 then '10-19'
    when score between 20 and 29 then '20-29'
    ...
    else '90-99' end as range
  from scores) t
group by t.range

সম্পাদনা: মন্তব্য দেখুন


এটি সম্ভবত এসকিউএল সার্ভারের সংস্করণ হিসাবে আমি ব্যবহার করছি তবে আপনার উদাহরণটি কাজ করার জন্য (আমি তাদের ভোট দেওয়ার আগে বিষয়গুলি পরীক্ষা করে দেখি) 'কেস' পরে প্রতিটি 'কখন' পরে 'স্কোর' নিয়ে যেতে হয়েছিল।
রন টফিন

3
আপনি ঠিক বলেছেন, এবং সংশোধনের জন্য ধন্যবাদ। স্পষ্টত আপনি যখন 'কেস' কীওয়ার্ডের পরে ভেরিয়েবলটি রাখেন তখন আপনি কেবল সঠিক মিল করতে পারেন, এক্সপ্রেশন নয়। আমি তাদের জিজ্ঞাসা থেকে প্রশ্নের উত্তর থেকে যতটা শিখি। :-)
কেন পল

23

পোস্টগ্রিসে ( ||স্ট্রিং কনটেনটেশন অপারেটরটি কোথায় ):

select (score/10)*10 || '-' || (score/10)*10+9 as scorerange, count(*)
from scores
group by score/10
order by 1

দেয়:

 scorerange | count 
------------+-------
 0-9        |    11
 10-19      |    14
 20-29      |     3
 30-39      |     2

11

জেমস কুরানের উত্তরটি আমার মতে সবচেয়ে সংক্ষিপ্ত ছিল, তবে আউটপুটটি সঠিক ছিল না। এসকিউএল সার্ভারের জন্য সহজ বক্তব্যটি নিম্নরূপ:

SELECT 
    [score range] = CAST((Score/10)*10 AS VARCHAR) + ' - ' + CAST((Score/10)*10+9 AS VARCHAR), 
    [number of occurrences] = COUNT(*)
FROM #Scores
GROUP BY Score/10
ORDER BY Score/10

এটি ধরে নিয়েছে যে আমি এটি পরীক্ষার জন্য একটি # স্কোরস অস্থায়ী টেবিলটি ধরেছিলাম, আমি 0 এবং 99 এর মধ্যে এলোমেলো সংখ্যা সহ 100 টি সারি তৈরি করেছি।


1
আহ ... টেবিলটি তৈরি করতে আসলে সময় নেওয়ার সুবিধা রয়েছে। (আমি খুব কম পরিসরের তুলনায় খুব কম সারি সহ একটি বিদ্যমান টেবিল ব্যবহার করেছি)
জেমস কারান

5
create table scores (
   user_id int,
   score int
)

select t.range as [score range], count(*) as [number of occurences]
from (
      select user_id,
         case when score >= 0 and score < 10 then '0-9'
         case when score >= 10 and score < 20 then '10-19'
         ...
         else '90-99' as range
     from scores) t
group by t.range

ধন্যবাদ! আমি এটি চেষ্টা করেছি এবং বেসিক ধারণাটি দুর্দান্ত কাজ করে, যদিও আমার যে সিনট্যাক্সটি ব্যবহার করতে হয়েছিল তা কিছুটা আলাদা। কেবলমাত্র প্রথম "কেস" কীওয়ার্ডটির প্রয়োজন হয় এবং তারপরে শেষ শর্তের পরে "হিসাবে পরিসর" এর আগে আপনার কীওয়ার্ডটি "শেষ" প্রয়োজন need তা ছাড়াও দুর্দান্ত কাজ করেছেন- ধন্যবাদ!
হিউজ

5
select cast(score/10 as varchar) + '-' + cast(score/10+9 as varchar), 
       count(*)
from scores
group by score/10

আমি এটি পছন্দ করি তবে আপনি যদি কোয়েরিটি প্রদর্শন করতে যাচ্ছেন তবে আপনাকে কোয়েরির বাইরে রেঞ্জগুলি ঠিক করতে হবে।
tvanfosson

যদি আপনি নিজের উত্তরটি স্থির করে নেওয়ার সিদ্ধান্ত নেন তবে আপনার উভয়টির জন্য প্রথম লাইনে আপনার স্কোর / 10 পরিবর্তন করতে হবে (স্কোর / 10) * 10 তাদের উভয়ের জন্য অন্যথায় আপনি 30-39 এর পরিবর্তে 3 - 12 পাবেন ইত্যাদি আমার পোস্ট অনুসারে নীচে আপনি সঠিক ক্রমে ফলাফল পেতে একটি অর্ডার যোগ করতে পারেন।
তীমথিয় ওয়াল্টারস 24:58

5

এটি আপনাকে ব্যাপ্তি নির্দিষ্ট করতে না দেয় এবং এসকিউএল সার্ভার অজ্ঞেস্টিক হওয়া উচিত। ম্যাথ এফটিডব্লিউ!

SELECT CONCAT(range,'-',range+9), COUNT(range)
FROM (
  SELECT 
    score - (score % 10) as range
  FROM scores
)

3

আমি এটি কিছুটা ভিন্নভাবে করব যাতে এটি প্রতিটি ক্ষেত্রে কোনও সংজ্ঞা না দিয়ে স্কেল করে:

select t.range as [score range], count(*) as [number of occurences]
from (
  select FLOOR(score/10) as range
  from scores) t
group by t.range

পরীক্ষিত নয়, তবে আপনি ধারণাটি পেয়েছেন ...


2
declare @RangeWidth int

set @RangeWidth = 10

select
   Floor(Score/@RangeWidth) as LowerBound,
   Floor(Score/@RangeWidth)+@RangeWidth as UpperBound,
   Count(*)
From
   ScoreTable
group by
   Floor(Score/@RangeWidth)

1
select t.blah as [score range], count(*) as [number of occurences]
from (
  select case 
    when score between  0 and  9 then ' 0-9 '
    when score between 10 and 19 then '10-19'
    when score between 20 and 29 then '20-29'
    ...
    else '90-99' end as blah
  from scores) t
group by t.blah

আপনি মাইএসকিউএলে থাকলে 'রেঞ্জ' ব্যতীত অন্য কোনও শব্দ ব্যবহার করেছেন তা নিশ্চিত করুন বা উপরের উদাহরণটি চালানোর জন্য আপনি একটি ত্রুটি পাবেন।


1

( Range) এ বাছাই করা কলামটি একটি স্ট্রিং হওয়ায় সংখ্যার বাছাইয়ের পরিবর্তে স্ট্রিং / শব্দ সাজানো ব্যবহৃত হয়।

যতক্ষণ না স্ট্রিংয়ের সংখ্যা দৈর্ঘ্য প্যাড করার জন্য শূন্য থাকে ততক্ষণ বাছাই করা শব্দার্থবিজ্ঞান অনুসারে সঠিক হওয়া উচিত:

SELECT t.range AS ScoreRange,
       COUNT(*) AS NumberOfOccurrences
  FROM (SELECT CASE
                    WHEN score BETWEEN 0 AND 9 THEN '00-09'
                    WHEN score BETWEEN 10 AND 19 THEN '10-19'
                    ELSE '20-99'
               END AS Range
          FROM Scores) t
 GROUP BY t.Range

যদি পরিসরটি মিশ্রিত হয় তবে কেবল অতিরিক্ত শূন্য প্যাড করুন:

SELECT t.range AS ScoreRange,
       COUNT(*) AS NumberOfOccurrences
  FROM (SELECT CASE
                    WHEN score BETWEEN 0 AND 9 THEN '000-009'
                    WHEN score BETWEEN 10 AND 19 THEN '010-019'
                    WHEN score BETWEEN 20 AND 99 THEN '020-099'
                    ELSE '100-999'
               END AS Range
          FROM Scores) t
 GROUP BY t.Range

1

চেষ্টা

SELECT (str(range) + "-" + str(range + 9) ) AS [Score range], COUNT(score) AS [number of occurances]
FROM (SELECT  score,  int(score / 10 ) * 10  AS range  FROM scoredata )  
GROUP BY range;

3
আপনার ক্যোয়ারী কীভাবে সমস্যাটি সমাধান করে সে সম্পর্কে কিছু ব্যাখ্যা যুক্ত করতে পারলে এটি সহায়ক হবে।
ডেভলিন কার্নেট

-1

সম্ভবত আপনি এই জাতীয় জিনিসগুলি চালিয়ে যাওয়ার বিষয়ে জিজ্ঞাসা করছেন ...

অবশ্যই আপনি কোয়েরিগুলির জন্য একটি পূর্ণ টেবিল স্ক্যান শুরু করবেন এবং যদি স্কোরগুলি দীর্ঘ করতে হবে (সমষ্টিগুলি) বড় হওয়াতে আপনি আরও ভাল পারফরম্যান্স সমাধান চান তবে আপনি একটি গৌণ সারণী তৈরি করতে পারেন এবং নিয়মগুলি ব্যবহার করতে পারেন যেমন on insert- আপনি এটি সন্ধান করতে পারে।

সমস্ত আরডিবিএমএস ইঞ্জিনের বিধি নেই, যদিও!

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