এসকিউএল নির্বাচন নম্বর সীমা


19

সারি হিসাবে সারি হিসাবে বিভিন্ন সংখ্যা অর্জন করা আমার পক্ষে বেশ কঠিন মনে হয়েছে MySQL

উদাহরণস্বরূপ 1-5 পরিসীমা দ্বারা অর্জন করা হয়:

SELECT 1 
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5

ফলাফল হবে:

1
2
3
4
5

0-99 এর জন্য আমি দুটি 0-9 সারণিতে যোগদান করতে পারবো:

CREATE TABLE nums as
SELECT 0 as num
UNION
SELECT 1 
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6 
UNION
SELECT 7
UNION
SELECT 8
UNION
SELECT 9
;

Select n.num*10+nums.num v 
From nums n cross join nums

আমি এই সমস্ত লিখতে UNIONএবং কোড সঙ্কুচিত করার উপায় খুঁজছি ক্লান্ত ।

মাইএসকিউএল বা কোনও এসকিউএল সিনট্যাক্সে কীভাবে এটি গল্ফ করবেন (উদাহরণস্বরূপ 0-1,000,000 পরিসীমা)?

অতিরিক্ত পয়েন্টের জন্য দেওয়া হয়:

  • একক বিবৃতি
  • কোন পদ্ধতি
  • কোনও ভেরিয়েবল নেই
  • কোনও ডিডিএল বিবৃতি নেই
  • কেবলমাত্র DQL স্টেটমেন্ট

2
এটি মেটাতে বা ডিবা.স্ট্যাকেক্সেঞ্জের ডট কম বা এসকিউএল থ্রেডে গল্ফিংয়ের টিপসে থাকতে পারে কিনা তা নিশ্চিত ।
ব্র্যাডিসি

8
ভোটারদের বন্ধ করতে: এটি একটি বিষয়ভিত্তিক চ্যালেঞ্জ; গল্ফিং কোড সম্পর্কিত যে প্রশ্নগুলি চ্যালেঞ্জ নয় সেগুলি বিষয়বস্তু সম্পর্কিত টিপস প্রশ্ন হিসাবে বিবেচিত হয়।
হাইপারনিউটারিনো

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

@ আর্নল্ড যে আশ্চর্যজনক!
ডিমগোল্ড

2
"কোনো এসকিউএল" পোস্টগ্রি অন্তর্ভুক্ত থাকে, দেখতে generate_series()। আমাদের এখানে কয়েকটি ব্যবহারের উদাহরণ রয়েছে।
manatwork

উত্তর:


9

এসকিউএল উপভাষার জন্য যা স্ক্লাইটের মতো পুনরাবৃত্ত সিটিই সমর্থন করে , আপনি নিম্নলিখিতগুলির মতো কিছু করতে পারেন:

WITH RECURSIVE f(x) AS
(
  SELECT 1 UNION ALL SELECT x + 1 FROM f LIMIT 1000000
)
SELECT x
FROM f;

এটি কোনও বিদ্যমান টেবিলের উপর নির্ভর করে না এবং আপনি LTD ক্লজটি পছন্দ অনুযায়ী পরিবর্তন করতে পারেন। আমি স্ট্যাকওভারফ্লোতে মূলত এর একটি বৈকল্পিক দেখেছি।


2
চমৎকার। এখানে এমএস এসকিউএল-এ কাজ করে এমন একটি গল্ফযুক্ত সংস্করণ রয়েছে: WITH t AS(SELECT 1n UNION ALL SELECT n+1FROM t WHERE n<36)SELECT n FROM t বিভিন্ন প্রান্তের জন্য, কেবলমাত্র 1এবং 36আপনি যা চান তা পরিবর্তন করুন ।
ব্র্যাডিসি

1
ওফস, যদি আপনি এমএস এসকিউএল এ 100 টিরও বেশি সারি চান তবে আপনার option (maxrecursion 0)উপরের বিবৃতিটির শেষের দিকে আপনাকে যোগ করতে হবে, অন্যথায় এটি 100 এর বেশি সংখ্যার পুনরাবৃত্তির জন্য ত্রুটিযুক্ত maxrecursionহয়েছে a ।
ব্র্যাডিসি

6

একই থেকে @ BradC এর পদ্ধতি

আমি এমএস এসকিউএল ব্যবহার করেছি, যার মধ্যে একটি টেবিল রয়েছে - [master]2048 এর মধ্যে -1 এর সংখ্যার ব্যাপ্তি। আপনি BETWEENআপনার পরিসর তৈরি করতে অপারেটরটি ব্যবহার করতে পারেন ।

SELECT DISTINCT(number)
FROM master..[spt_values] 
WHERE number BETWEEN 1 AND 5

আপনি যদি এইটি গল্ফ করতে চান তবে আপনি এটি করতে পারেন:

SELECT TOP 5 ROW_NUMBER()OVER(ORDER BY number)FROM master..spt_values

1
গল্ফ করার জন্য আপনি 2 বাইট সংরক্ষণ করুনWHERE number>0AND number<21
ব্র্যাডিসি

কেন আপনি আলাদা ব্যবহার করবেন? অপ্রয়োজনীয় মনে হচ্ছে।
যাদু অক্টোপাস উরন

1
@ MagicOctopusUrn কারণ এই টেবিলটিতে নকল সংখ্যা রয়েছে।
অলিভার

1
হ্যাঁ আপনাকে হয় DISTINCT ব্যবহার করতে হবে বা যেখানে '= পি' টাইপ ব্যবহার করতে হবে। ভিন্নতা কিছুটা খাটো হয়।
ব্র্যাডিসি

1
@ ব্র্যাডসি, বাSELECT DISTINCT(number+2)... WHERE number<19
পিটার টেলর

5

PostgreSQL, 35 বাইট

পোস্টগ্র্যাস এসকিউএলএটি সহজ:

SELECT * FROM generate_series(1,5)

আপনার যদি এটির নাম প্রয়োজন হয়:

SELECT num FROM generate_series(1,5)AS a(num)

আপনি টাইমস্ট্যাম্পগুলির সাহায্যে এটিও করতে পারেন। https://www.postgresql.org/docs/9.5/static/functions-srf.html


2
আমার ধারণা আমি
পোস্টগ্র্রেসে চলেছি

4

এই পোস্টটি থেকে দুর্দান্ত বিকল্প (@ আরনাউল্ড দ্বারা পাওয়া):

SELECT id%1000001 as num
FROM <any_large_table>
GROUP BY num

আমার জন্য - এটি চ্যালেঞ্জটি বেশ সমাধান করে।


এটি ইতিমধ্যে একটি বিদ্যমান টেবিলের উপর নির্ভর করছে বলে মনে হচ্ছে ইতিমধ্যে idখুব বড় মানের মাধ্যমে একটি ক্ষেত্র জনবহুল। খুব সুন্দর ডাটাবেস নির্দিষ্ট, এবং আপনি যদি একটি সারি মিস করতে পারেন, যদি বলা হয় যে কেউ আইডি = 4021 মুছে ফেলেছে
ব্র্যাডিসি

হ্যাঁ, তবে এটি তুলনামূলকভাবে ছোট রেঞ্জের জন্য সত্যিই ভাল (1-7 দিনের জন্য, 1-12 মাসের জন্য ইত্যাদি ...)
ডিমগোল্ড

4

পোস্টগ্রিগ এসকিউএল নির্দিষ্ট

generate_series()একটি সেট জেনারেট করে, তাই আপনি এটিকে কেবল fromঅনুচ্ছেদে নয়, যেখানেই সেট সেট হতে পারে সেখানে ব্যবহার করতে পারেন:

psql=# select generate_series(10, 20, 3);
 generate_series 
-----------------
              10
              13
              16
              19
(4 rows)

আপনি সরাসরি সেটে অপারেশনও করতে পারেন:

psql=# select 2000 + generate_series(10, 20, 3) * 2;
 ?column? 
----------
     2020
     2026
     2032
     2038
(4 rows)

যদি একাধিক সেটের সমান দৈর্ঘ্য থাকে তবে আপনি সেগুলি সমান্তরালভাবে অতিক্রম করতে পারেন:

psql=# select generate_series(1, 3), generate_series(4, 6);
 generate_series | generate_series 
-----------------+-----------------
               1 |               4
               2 |               5
               3 |               6
(3 rows)

বিভিন্ন দৈর্ঘ্যের সাথে সেটগুলির জন্য কার্টেসিয়ান পণ্য উত্পন্ন হয়:

psql=# select generate_series(1, 3), generate_series(4, 5);
 generate_series | generate_series 
-----------------+-----------------
               1 |               4
               2 |               5
               3 |               4
               1 |               5
               2 |               4
               3 |               5
(6 rows)

তবে আপনি যদি এগুলিকে fromক্লজে ব্যবহার করেন তবে আপনি একই দৈর্ঘ্যের সেটগুলির জন্য কার্টেসিয়ান পণ্যও পাবেন:

psql=# select * from generate_series(1, 2), generate_series(3, 4) second;
 generate_series | second 
-----------------+--------
               1 |      3
               1 |      4
               2 |      3
               2 |      4
(4 rows)

এটি টাইমস্ট্যাম্পগুলির সেটও তৈরি করতে পারে। উদাহরণস্বরূপ আপনি 2000-06-30 এ জন্মগ্রহণ করেছেন এবং আপনি জানতে চান যে কোন সপ্তাহে আপনি আপনার জন্মদিনটি সপ্তাহান্তে উদযাপন করেছেন:

psql=# select to_char(generate_series, 'YYYY - Day') from generate_series('2000-06-30', current_date, interval '1 year') where to_char(generate_series, 'D') in ('1', '7');
     to_char      
------------------
 2001 - Saturday 
 2002 - Sunday   
 2007 - Saturday 
 2012 - Saturday 
 2013 - Sunday   
(5 rows)

3

এমএস এসকিউএল masterনামক ডেটাবেজে একটি অননুমোদিত সিস্টেম টেবিল রয়েছে spt_values। অন্যান্য জিনিসের মধ্যে এটিতে 0 থেকে 2047 পর্যন্ত বিভিন্ন সংখ্যার সংখ্যা রয়েছে:

--returns 0 to 2,047
SELECT number n 
FROM master..spt_values
WHERE TYPE='P'

একটি সংখ্যা টেবিল হিসাবে কেবল নিজেই দরকারী, তবে একটি সিটিইতে আপনি বেশ কয়েকটি বড় সংখ্যা পেতে পারেন:

--returns 0 to 4,194,304
WITH x AS(SELECT number n FROM master..spt_values WHERE TYPE='P')
SELECT 2048*x.a+*y.a
FROM x,x y
ORDER BY 1

3

(এমএস-এসকিউএলে এগুলি কাজ করে, তারা মাইএসকিউএল বা অন্যান্য প্ল্যাটফর্মের জন্য কাজ করে কিনা তা নিশ্চিত নয়))

ছোট সেট (অর্ডারযুক্ত বা অ-অর্ডারযুক্ত) জন্য, VALUESকনস্ট্রাক্টরটি ব্যবহার করুন :

--Generates 0-9
SELECT a 
FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))x(a)

(এটি কোনও কিছুর জন্য কাজ করে, যদিও স্ট্রিংগুলি সমস্ত পুনরাবৃত্ত একক উদ্ধৃতি দিয়ে বেশ দীর্ঘ পেতে পারে))

তারপরে আপনি নামযুক্ত সিটিই (সাধারণ টেবিল এক্সপ্রেশন) ব্যবহার করে ক্রস-গুণ করতে পারেন যাতে আপনাকে এটি পুনরাবৃত্তি করতে হবে না:

--Generates 0-999
WITH x AS(SELECT a FROM(VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))x(a))
SELECT 100*x.a+10*y.a+z.a 
FROM x,x y,x z
ORDER BY 1

সেখানে অনেকগুলি অন্যান্য কৌশল রয়েছে, "এসকিউএল একটি নম্বর টেবিল উত্পন্ন করছে" দেখুন, যদিও বেশিরভাগ গল্ফিংয়ের জন্য অনুকূল নয়।


1
এটি কি limit Yস্বেচ্ছাসেবী রেঞ্জ তৈরির সাথে কাজ করবে ?
রড

1
@ রড এমএস-এসকিউএল-এ আপনাকে ব্যবহার করতে হবেSELECT TOP 250 ...
ব্র্যাডিসি

ওহ, আমি
রড

মাইএসকিউএলে কাজ করে না, তবে এখনও দরকারী :)
ডিমগল্ড

2

আরও একটি বিকল্প, এটি এমএস এসকিউএল 2016 এবং তারপরে নির্দিষ্ট:

SELECT value v
FROM STRING_SPLIT('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16', ',')

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


2

টি এসকিউএল, 98 বাইট

WITH H AS(SELECT 0i UNION ALL SELECT i+1FROM H WHERE i<99)SELECT H.i+1e4*A.i+B.i*1e2FROM H,H A,H B
  • ✓ একক বিবৃতি
  • Procedures কোন পদ্ধতি
  • Vari কোনও ভেরিয়েবল নেই
  • D কোনও ডিডিএল বিবৃতি নেই
  • D কেবলমাত্র DQL স্টেটমেন্ট

এটি ল্যাঞ্জেলজিজেমের উত্তরের একটি সুন্দর পরিপাটি টি-এসকিউএল সংস্করণ । অভিজাতরাও একটি ঝরঝরে কৌশল trick
ব্র্যাডিসি

1

এসকিউএল সার্ভারের জন্য আর একটি ...

WITH 
    cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)),   -- 10
    cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b),                             -- 100
    cte_Tally (n) AS (
        SELECT TOP (<how many ROWS do you want?>)
            ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
        FROM
            cte_n2 a CROSS JOIN cte_n2 b                                                    -- 10,000
        )
SELECT 
    t.n
FROM
    cte_Tally t;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.