टी-एसक्यूएल में गोल्फ के लिए टिप्स


16

टी-एसक्यूएल में गोल्फिंग के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं जो सामान्य रूप से टी-एसक्यूएल के लिए कुछ हद तक विशिष्ट गोल्फ समस्याओं को लागू करने के लिए लागू किया जा सकता है। कृपया प्रति उत्तर एक टिप पोस्ट करें।

मूल विचार के लिए मार्कोग को धन्यवाद। :)


एक टिप - गोल्फिंग के लिए एक अलग भाषा का उपयोग करें। Sql के उत्तर आमतौर पर बहुत कम या बिल्कुल नहीं मिलते हैं।
t-clausen.dk

जवाबों:


16

मेरी चाल का सामान्य बैग ::

  • @ t-sql में एक मान्य चर है।
  • T-sql 2012 iifमें VB स्टाइल केस स्टेटमेंट जोड़ा गया । यह लगभग हमेशा एक समकक्ष से छोटा होता है if else
  • \एक पैसे के प्रकार में 0 के रूप में एक संख्या को इनिशियलाइज़ करने का एक उपयोगी तरीका है। आप एक मान को फ्लोट में जोड़कर बदल सकते हैं e। उदाहरण के लिए 4eया \kजो k मान 0.00 पैसे पर सेट होगा।
  • rCTE100 से कम प्रविष्टियों की संख्या तालिका बनाने का सबसे अच्छा तरीका प्रतीत होता है। Spt_values ​​का उपयोग करने से भी छोटा। यदि आपको 100 से अधिक की आवश्यकता है, तो सम्मिलित हों और उन्हें जोड़ दें।
  • += और अन्य मिश्रित ऑपरेटरों को 2008 में जोड़ा गया था। उनका उपयोग यह कुछ पात्रों को बचाता है।
  • आमतौर पर अलियासिंग उद्देश्यों के लिए साहित्य एक अच्छा पर्याप्त परिसीमन है। आपको शायद ही किसी स्थान या ए की आवश्यकता है ;
  • यदि आपको उनकी आवश्यकता है तो ANSI SQL जॉइन का उपयोग करें। Select*from A,B where conditionसे छोटा हैselect*from A join b on condition
  • यदि आपको यह आश्वासन दिया जा सकता है कि आपका लूप लूप पहला पुनरावृत्ति करेगा, तो इसे एक डू-टाइम स्टाइल gotoलूप के रूप में फिर से लिखना सबसे अच्छा है ।
  • STR()एक स्ट्रिंग में एक इंट को चालू करने के लिए सबसे छोटा कार्य है। यदि आप एक से अधिक रूपांतरण कर रहे हैं या concatफ़ंक्शन पर विचार करने के लिए कई अलग-अलग डेटाैटेस को समाप्‍त करने की आवश्यकता हो सकती है । जैसे 'hello'+str(@)की तुलना में छोटा है concat('hello',@), लेकिन इससे hello+str(@)+str(@a)अधिक लंबा हैconcat('hello',@,@a)

उदाहरण के लिए ये दोनों शब्दार्थ के समकक्ष हैं।

while @<100begin/*code*/set @+=1 end
s:/*code*/set @+=1if @<100goto s

आप Valuesतालिका या उपकुंजी बनाने के लिए उपयोग कर सकते हैं । यह वास्तव में केवल एक लाभ होगा यदि आपको कुछ निरंतर पंक्तियों की आवश्यकता होती है।


मेरे लिए, $ एक पैसा प्रकार में 0 के रूप में एक संख्या को शुरू करने के लिए \ _ की तुलना में थोड़ा अधिक स्पष्ट है। YMMV
user1443098

5

एसक्यूएल का उपयोग कर कोड संपीड़न

एसक्यूएल वर्डी है, स्कोर उच्च है, और जितना हम प्यार करते हैं, SELECT FROM WHEREहर उपयोग के साथ 23 बाइट्स खर्च होते हैं। आप इन और अन्य दोहराए गए शब्दों या पूरे कोड स्निपेट को संक्षिप्त कर सकते हैं। ऐसा करने से बार-बार कोड की सीमांत लागत 1 बाइट कम हो जाएगी! *

यह कैसे काम करता है:

  • एक चर घोषित किया जाता है और संपीड़ित SQL कोड असाइन किया जाता है
  • एक तालिका चर को संशोधित करती है। प्रत्येक पंक्ति चर का खंडन करती है।
  • संशोधित चर निष्पादित किया गया है।

समस्या:

अपफ्रंट कॉस्ट 100 बाइट्स के करीब है और रिप्लेसमेंट टेबल की प्रत्येक पंक्ति की कीमत 6 बाइट्स है। इस तरह के तर्क बहुत प्रभावी नहीं होंगे जब तक कि आप बहुत सारे कोड के साथ काम नहीं कर रहे हैं जिन्हें आप ट्रिम नहीं कर सकते हैं या चुनौती संपीड़न-आधारित है।

यहाँ एक उदाहरण है

चुनौती 2,3 के अंतिम 10 गुणकों को प्राप्त करना है, और 5 को n तक ले जाना है। मान लें कि यह ( 343 बाइट्स गॉल्फर्ड ) सबसे अच्छा उपाय है जिसे मैं ले सकता हूं:

WITH x AS(
    SELECT 99 n
UNION ALL 
    SELECT n-1
    FROM x
    WHERE n>1
)
SELECT w.n,t.n,f.n
FROM
    (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%2=0
    )w
,
    (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%3=0
    )t
,   (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%5=0
    )f
WHERE w.r=t.r AND w.r=f.r AND w.r<11
ORDER BY 1

कोड संपीड़ित होने के बाद उदाहरण

यह ऊपर के रूप में एक ही कोड निष्पादित करता है, ~ 302 बाइट्स गोल्फ है

DECLARE @a CHAR(999)='
WITH x AS(!99n UNION ALL !n-1 @x#n>1)
!w.n,t.n,f.n@$2=0)w,$3=0)t,$5=0)f
#w.r=t.r AND w.r=f.r AND w.r<11^1'

SELECT @a=REPLACE(@a,LEFT(i,1),SUBSTRING(i,2,99))
FROM(VALUES
  ('$(!n,ROW_NUMBER()OVER(^n DESC)r@x#n%'),
  ('! SELECT '),
  ('@ FROM '),
  ('# WHERE '),
  ('^ ORDER BY ')
)x(i)

EXEC(@a)

महान रणनीति, वह बहु-प्रतिस्थापित शैली अधिक पारंपरिक परिदृश्यों में भी उपयोगी हो सकती है।
ब्रैडेक

1
कुछ परीक्षण के बाद, मैंने निर्धारित किया है कि यदि आपके प्रतिस्थापन की सूची में 7 या उससे कम आइटम हैं, तो आप SELECT @=REPLACE(@,i,j)FROM(VALUES(...)x(i,j)एकल कॉलम LEFT()और का उपयोग करने के बजाय बाइट्स को बचाएंगे SUBSTRING()। यदि आपके पास 8 या अधिक है, तो अतिरिक्त उद्धरण और अल्पविराम से बचना एक अच्छा व्यापार है।
ब्रैडक

वास्तव में 4 या उससे कम प्रतिस्थापन के लिए, आप बाइट्स को एक पुराने जमाने के साथ SET @=REPLACE(REPLACE(REPLACE(...
बचाएंगे

4

यहाँ एक अजीब बात है। यह एक कॉलम में मानों को एकल ट्यूपल में बदल देगा।

संपादित करें: टिप्पणियों के लिए धन्यवाद। ऐसा लगता है कि XML टैग के बिना रोलिंग का सबसे छोटा तरीका है:

SELECT (SELECT column1+''
FROM table
ORDER BY column1
FOR XML PATH(''))

नोट: यदि XML एक वैध आउटपुट है, तो आप बाहरी चयन और पार्न्स को छोड़ सकते हैं। इसके अलावा column1+'', केवल स्ट्रिंग्स के लिए काम करता है। संख्या प्रकारों के लिए यह करना सबसे अच्छा हैcolumn1+0


1
वास्तव में यह वापस आ जाएगी <column_name>value1</column_name><column_name>value2</column_name>...। एक कॉलम से सीएसवी लेने DECLARE @ VARCHAR(MAX)='';SELECT @+=column_name+',' FROM table_name;SELECT @के लिए आप (माइकलबी की पहली टिप के लिए धन्यवाद) कर सकते हैं जो वापस आ जाएगा value1,value2,...। हालाँकि, यह वास्तव में आपके XML ट्रिक से अधिक 9 अक्षर है :(
जैकब

1
ध्यान दें कि आप इसे छोटा कर सकते हैं। Ltrimचयन के रूप में आवश्यक (चयन ( '') एक्सएमएल पथ के लिए ...) एक रिटर्न नहीं है nvarchar(max)। इसके अलावा, स्तंभ चीज़ को हल करने के लिए बस एक गैर-उत्परिवर्ती अभिव्यक्ति का उपयोग करें। संख्यात्मक के लिए आप कर सकते हैं v+0, स्ट्रिंग जोड़ने के लिए खाली स्ट्रिंग आदि। हालांकि मैं वास्तव में इसे एक गोल्फ टिप नहीं मानता हूं, यह सिर्फ दुख की बात है कि एसक्यूएल सर्वर में प्रश्न कैसे लिखें।
माइकल बी

3

टी-एसक्यूएल में कुछ बिटवाइज़ ऑपरेटरों का उपयोग करना संभव है ।

मेरे पास कोई ठोस उदाहरण नहीं है, लेकिन मेरा मानना ​​है कि टी-एसक्यूएल में गोल्फिंग करते समय यह एक अच्छी जानकारी है।


1
यह बहुत मान्य है। जैसे हालत लिखने के बजाय x=0 or y=0, आप लिख सकते हैं कि तार्किक रूप से समतुल्य है x|y=0जो काफी कुछ बाइट्स बचाता है!
माइकल बी


3

वैज्ञानिक संकेतन बहुत बड़ी और बहुत छोटी संख्याओं को व्यक्त करने की एक छोटी विधि है, जैसे select 1000000000= select 1E9और select 0.000001= select 1E-6


2

माइकल बी ने एक अंक तालिका के लिए एक पुनरावर्ती सीटीई का उपयोग करने का उल्लेख किया , लेकिन एक उदाहरण नहीं दिखाया। यहाँ एक MS-SQL संस्करण है जो हमने इस अन्य सूत्र में काम किया है :

--ungolfed
WITH t AS (
    SELECT 1 n 
    UNION ALL 
    SELECT n + 1
    FROM t 
    WHERE n < 99)
SELECT n FROM t

--golfed
WITH t AS(SELECT 1n UNION ALL SELECT n+1FROM t WHERE n<99)SELECT n FROM t

ध्यान दें कि आप प्रारंभिक मूल्य ( 1 n), अंतराल ( n + 1) और समाप्ति मूल्य ( n < 99) बदल सकते हैं।

यदि आपको 100 से अधिक पंक्तियों की आवश्यकता है, हालांकि, आपको जोड़ना होगा option (maxrecursion 0):

WITH t AS(SELECT 0n UNION ALL SELECT n+1FROM t WHERE n<9999)
SELECT n FROM t option(maxrecursion 0)

या स्वयं rCTE में शामिल हों:

WITH t AS(SELECT 0n UNION ALL SELECT n+1FROM t WHERE n<99)
SELECT 100*z.n+t.n FROM t,t z

हालांकि यह अंतिम एक के बिना संख्यात्मक क्रम में लौटने की गारंटी नहीं है ORDER BY 1


2

बहुत लंबे तार के लिए GZIP संपीड़न का उपयोग करें!

इसलिए मुझे पता था कि SQL 2016 ने एक COMPRESSफ़ंक्शन (और एक DECOMPRESSफ़ंक्शन) जोड़ा है , जो (अंत में) GZIP को एक स्ट्रिंग या बाइनरी की क्षमता लाता है।

समस्या यह है कि यह तुरंत स्पष्ट नहीं है कि गोल्फ के लिए इसका लाभ कैसे उठाया जाए; COMPRESSएक स्ट्रिंग ले सकता है लेकिन एक रिटर्न देता है VARBINARY, जो बाइट्स में छोटा होता है (जब एक SQL VARBINARYफ़ील्ड में संग्रहीत होता है ), लेकिन अधिक लंबा होता है वर्णों (रॉ एक्सएक्सएक्स) में है।

मैंने पहले भी इसके साथ खेला है, लेकिन मैं आखिरकार एसओ पर इस पुराने जवाब के आधार पर एक काम करने वाले संस्करण को एक साथ रखने में सक्षम था । वह पोस्ट नए GZIP फ़ंक्शंस का उपयोग नहीं करता है, लेकिन यह VARBINARYएक बेस -64 एनकोडेड स्ट्रिंग में परिवर्तित करता है । हमें बस नए कार्यों को सही स्थान पर सम्मिलित करने की आवश्यकता है, और इसे थोड़ा ऊपर उठाएं।

यहां वह कोड है जिसका उपयोग करके आप अपने बहुत लंबे स्ट्रिंग को बेस -64 एनकोडेड कंप्रेस्ड स्ट्रिंग में बदल सकते हैं:

DECLARE @s VARCHAR(MAX)='Your really long string goes right here'
SELECT CONVERT(VARCHAR(MAX),(SELECT CONVERT(VARBINARY(MAX),COMPRESS(@s))
       FOR XML PATH(''),BINARY BASE64))

आउटपुट लें, और इसे मूल लॉन्ग स्ट्रिंग के स्थान पर अपने कोड में उपयोग करें:

--To use your compressed string and return the original:
DECLARE @e VARCHAR(MAX)='H4sIAAAAAAAEAIvMLy1SKEpNzMmpVMjJz0tXKC4pygRS6fmpxQpFmekZJQoZqUWpAGGwW5YnAAAA'
SELECT CAST(DECOMPRESS(CAST(@e as XML).value('.','varbinary(max)'))AS varchar(max))

तो अपने मूल कोड के बजाय ( 1471 बाइट्स )

SELECT'Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate — we can not consecrate — we can not hallow — this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us — that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion — that we here highly resolve that these dead shall not have died in vain — that this nation, under God, shall have a new birth of freedom — and that government of the people, by the people, for the people, shall not perish from the earth.'

आपके पास यह ( 1034 बाइट्स ) होगा:

SELECT CAST(DECOMPRESS(CAST('H4sIAAAAAAAEAGVUW47bMAy8Cg/g5hD9aLFA0a8C/aYt2hZWEVNJjpGT5LodinE2i/0JIouPmeFQP3QrVCctQpwDVblKpptwqcSLkt3O3FbBeSy6LWujWUtbSTO1NVaaNLeYJbeBmLLslLlFzYNdTBKvEihm+hVHKe029CZBQpy44aYpighdil60RsvDmRtxSnQGEAasqUiPlX8bpxP91p126TeSF168PtNiYTTFa0y0cxmoSQWwhfZVDL8XPsBpAZLb40hVX9B+QgganCkp6kgOW5ET/fXmZ2mmwdF45NaSfJujpEA6ezfg6PErX8FDz2KEj9pIvUBJ63/E92xoBO3xP3Oi8iBxSTyJKY9ArQJSSiAltFhp8IuFEuBXL/TClc7RhmaXJ3prhJFxarq4KHNsvb6RtikcOkHhuuoGLkH7nE/0fcOIu9SJy4LAKrnKYKGmUdb2Qe3++hXSVpnKl+8rpoxh3t1HC9yVw4n+wA9jMVYwwGC4D3xBGOIY89rKtiwJwzINhkPfow0cAagzY8aj4sZMfFG1n90IKnEIZoEgrfDUvOmuBXT3COulaMM0kCieEdgNUOQsZ9gYEB4K8e0BYNwgbHNm2KBik4LCHgmhbxSigz1mYKPcane/Uxyo9D0bDN8oL0vS5/zYlC3DF7Gu+Ay872gQp9U7mDCzb2jPWN0ZaGJKwOJZx3QD9SvD6uEA4l2feHrvnv9lS93ojeu7ScHAAVFGme3tQOr94eGiZwuHSVeFduKDM70avwscZAtd++er+sqrp068VTf5C63D4HBdRfWtvwxcsYq2Ns8a96dvnTxMD7JYH0093+dQxcFU897DhLgO0V+RK0gdlbopj+cCzoRGPxX+89Se5u/dGPtzOIO5SAD5e3drL7LAfiXDyM13HE+d6CWZY26fjr7ZH+cPgFhJzPspK+FpbuvpP9RXxXK3BQAA'as XML).value('.','varbinary(max)'))AS varchar(max))

इस उत्तर को देखें जिसने मुझे लगभग 200 बाइट्स बचाए।

मैंने गणित नहीं किया है, लेकिन स्पष्ट रूप से ओवरहेड के कारण यह केवल बहुत लंबे तार के लिए प्रभावी होने जा रहा है। शायद अन्य स्थानों पर भी इसका उपयोग नहीं किया जा सकता है; मैंने पहले ही पता लगा लिया है कि आपके पास है SELECT, आप नहीं कर सकते PRINT, अन्यथा आपको मिलता है:

Xml data type methods are not allowed in expressions in this context.

संपादित करें : @ digscoop के सौजन्य से डिकम्प्रेस कोड का छोटा संस्करण :

बाहरी CASTका उपयोग करके एक अंतर्निहित रूपांतरण में परिवर्तन करके 10 बाइट्स सहेजें CONCAT:

SELECT CONCAT('',DECOMPRESS(CAST('encoded_string_here'as XML).value('.','varbinary(max)')))

आप XMLइसके बजाय एक प्रकार का चर भी घोषित कर सकते हैं VARCHAR(MAX), और आंतरिक पर सहेज सकते हैं CAST:

DECLARE @ XML='encoded_string_here'
SELECT CONCAT('',DECOMPRESS(@.value('.','varbinary(max)')))

यह अपने आप से थोड़ा लंबा है, लेकिन अगर आपको अन्य कारणों से एक चर में इसकी आवश्यकता है, तो यह मदद कर सकता है।


अच्छा, मैं एसक्यूएल नहीं जानता लेकिन यह अभी भी अच्छा लग रहा है
90

1

चुनौतियों के लिए टेबल बनाने और उपयोग करने के बारे में कुछ विचार:

1. SQL इनपुट को पहले से मौजूद टेबल के जरिए लिया जा सकता है

कोड गोल्फ इनपुट / आउटपुट तरीके :

SQL एक नामित तालिका से इनपुट ले सकता है

इस तालिका को इनपुट मानों के साथ बनाना और आबाद करना आपके बाइट कुल की ओर नहीं है, आप बस मान सकते हैं कि यह पहले से ही है।

इसका मतलब है कि आपकी गणना इनपुट तालिका से सरल चयन के माध्यम से आउटपुट कर सकती है:

SELECT 2*SQRT(a)FROM t

2. यदि संभव हो तो, वास्तव में एक तालिका न बनाएं

इसके बजाय (69 बाइट्स):

CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

बस करो (43 बाइट्स):

SELECT b FROM(VALUES(7),(14),(21),(99))t(b)

3. यदि संभव हो, तो तालिका का चयन करें में चयन करें

इसके बजाय (39 बाइट्स):

CREATE TABLE t(p INT)
INSERT t VALUES(2)

ऐसा करें (17 बाइट्स):

SELECT 2 p INTO t

4: कई स्तंभों को एक साथ मिलाने पर विचार करें

यहां दो भिन्नताएं हैं जो समान आउटपुट लौटाती हैं:

SELECT a,b FROM
(VALUES('W','Bob'),('X','Sam'),('Y','Darla'),('Z','Elizabeth'))t(a,b)

SELECT LEFT(a,1),SUBSTRING(a,2,99)FROM
(VALUES('WBob'),('XSam'),('YDarla'),('ZElizabeth'))t(a)

कुछ परीक्षण के बाद, शीर्ष संस्करण (एकाधिक कॉलम) 7 या उससे कम पंक्तियों के साथ छोटा लगता है , निचला संस्करण (LEFT और SUBSTRING के कारण) 8 या अधिक पंक्तियों के साथ छोटा होता है । आपके सटीक डेटा के आधार पर आपका माइलेज अलग-अलग हो सकता है।

5: पाठ के बहुत लंबे अनुक्रमों के लिए REPLACE और EXEC का उपयोग करें

आराम से श्रीदेवी के उत्कृष्ट उत्तर की नस में , यदि आपके पास 15 या अधिक मूल्य हैं , तो तत्वों के बीच REPLACEदोहराया '),('विभाजकों से छुटकारा पाने के लिए एक प्रतीक पर उपयोग करें :

114 वर्ण:

SELECT a FROM(VALUES('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H')
,('I'),('J'),('K'),('L'),('M'),('N'),('O'))t(a)

112 अक्षर:

DECLARE @ CHAR(999)=REPLACE('SELECT a FROM(VALUES(''
 A-B-C-D-E-F-G-H-I-J-K-L-M-N-O''))t(a)','-','''),(''')EXEC(@)

यदि आप पहले से ही हैं अन्य कारणों से डायनेमिक SQL का उपयोग (या कई रीप्लेस हैं), तो यह वह सीमा है जहाँ यह इस लायक है कि यह बहुत कम है।

6: चर का एक गुच्छा के बजाय नामित कॉलम के साथ एक चयन का उपयोग करें

यहाँ jmlt के शानदार जवाब से प्रेरित होकर, एक सेलेक्ट के माध्यम से फिर से उपयोग करें:

SELECT a+b+a+b+d+b+b+a+a+d+a+c+a+c+d+c+c+a+a
FROM(SELECT'Hare 'a,'Krishna 'b,'Rama 'c,'
'd)t

रिटर्न

Hare Krishna Hare Krishna 
Krishna Krishna Hare Hare 
Hare Rama Hare Rama 
Rama Rama Hare Hare 

(एमएस एसक्यूएल के लिए मैंने \tइन-लाइन रिटर्न में बदलाव CONCAT()किया , और +बाइट्स को बचाने के लिए बदल दिया )।


1

T-SQL सिंटैक्स हाइलाइटिंग के लिए अपना कोड टैग करें

इसके बजाय बस:

CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

इस तरह एक भाषा टैग शामिल करें:

<!-- language: lang-sql -->

    CREATE TABLE t(b INT)
    INSERT t VALUES(7),(14),(21),(99)
    SELECT b FROM t

और परिणाम होगा:

CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

1

MS SQL 2016 और SQL 2017 में नई सुविधाओं / कार्यों का लाभ उठाएं

यदि आपके पास काम करने के लिए स्थानीय प्रतियां नहीं हैं, तो आप StackExchange Data Explorer (SQL 2016) या dbfiddle.uk (SQL 2016 या SQL "vNext") के साथ ऑनलाइन खेल सकते हैं ।

STRING_SPLIT ( SQL 2016 और बाद में )

SELECT *
FROM STRING_SPLIT('one,two,three,four,five',',')

यदि आपको तालिका को उपनाम करने या स्तंभ नाम को संदर्भित करने की आवश्यकता है:

SELECT t.value
FROM STRING_SPLIT('one,two,three,four,five',',')t

TRIM ( SQL 2017 या बाद में )

से छोटा RTRIM()और निश्चित रूप से छोटा है LTRIM(RTRIM())

इसके अलावा शुरुआत या अंत से अन्य पात्रों या पात्रों के सेट को हटाने का विकल्प होता है :

SELECT TRIM('sq,0' FROM 'SQL Server 2000')

रिटर्न L Server 2

ट्रांसलेट ( SQL 2017 या बाद में )

TRANSLATEआपको नेस्टेड REPLACEकथनों के एक समूह के बजाय कई पात्रों को एक चरण में बदलने की अनुमति देता है । लेकिन बहुत ज्यादा जश्न नहीं मनाएं , यह केवल एकल एकल वर्णों को अलग-अलग एकल वर्णों के साथ बदलता है।

SELECT TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()');

दूसरी स्ट्रिंग में प्रत्येक वर्ण को 3rd स्ट्रिंग में संबंधित वर्ण से बदल दिया जाता है ।

लगता है जैसे हम कुछ के साथ पात्रों का एक गुच्छा समाप्त कर सकते हैं REPLACE(TRANSLATE('source string','ABCD','XXXX'),'X','')


साथ ही कुछ और दिलचस्प, जैसे कि CONCAT_WSऔर STRING_AGGशायद एक नज़र के लायक भी हैं।


1

पवित्र गाय, मैंने PARSENAME( SQL 2012 या उच्चतर ) आश्चर्य की खोज की है ।

फ़ंक्शन का निर्माण ऑब्जेक्ट नाम के हिस्सों को अलग करने के लिए किया गया था servername.dbname.dbo.tablename, लेकिन यह किसी भी डॉट-से-किए गए मान के लिए काम करता है । बस याद रखें कि यह दाईं ओर से गिना जाता है, बाईं ओर नहीं:

SELECT PARSENAME('a.b.c.d',1),      -- d
       PARSENAME('a.b.c.d',2),      -- c
       PARSENAME('a.b.c.d',3),      -- b
       PARSENAME('a.b.c.d',4)       -- a

यदि आपके पास 4 से कम बिंदु-अलग-अलग मान हैं, तो यह NULLशेष के लिए वापस आ जाएगा (लेकिन यह अभी भी बाएं से दाएं गिना जाता है ):

SELECT PARSENAME('a.b',1),      -- b
       PARSENAME('a.b',2),      -- a
       PARSENAME('a.b',3),      -- NULL
       PARSENAME('a.b',4)       -- NULL

यहाँ जादू कहाँ आता है, हालाँकि: इन-मेमोरी मल्टी-कॉलम टेबलSTRING_SPLIT बनाने के लिए इसे (2016 या उच्चतर) के साथ मिलाएं !!

पुराना और पर्दाफाश:

SELECT a,b,c FROM
(VALUES('Bob','W','Smith'),
       ('Sam','X','Johnson'),
       ('Darla','Y','Anderson'),
       ('Elizabeth','Z','Turner'))t(a,b,c)

नई गर्माहट:

SELECT PARSENAME(value,3)a,PARSENAME(value,2)b,PARSENAME(value,1)c
FROM string_split('Bob.W.Smith-Sam.X.Johnson-Darla.Y.Anderson-Elizabeth.Z.Turner','-')

स्पष्ट रूप से आपकी वास्तविक बचत तालिका के आकार और सामग्री पर निर्भर करती है, और वास्तव में आप इसका उपयोग कैसे कर रहे हैं।

ध्यान दें कि यदि आपके क्षेत्र निरंतर-चौड़ाई वाले हैं, तो शायद आप उपयोग करना LEFTऔर RIGHTउन्हें अलग करने के लिए बेहतर हैं PARSENAME(न केवल इसलिए कि फ़ंक्शन नाम छोटे हैं, बल्कि इसलिए भी कि आप विभाजकों को पूरी तरह से समाप्त कर सकते हैं)।


मुझे यकीन नहीं है कि जब PARSENAME बाहर आया था, लेकिन 2003 से इसका वर्णन करने वाले लेख हैं
t-clausen.dk

1

कुछ और असंबंधित टोटके जिन्हें मैंने देखा और संरक्षित करना चाहता था:

  1. GO #किसी ब्लॉक को एक विशिष्ट संख्या को दोहराने के लिए उपयोग करें

पॉल के उत्कृष्ट उत्तर पर इस चतुर चाल को देखा ।

PRINT'**********'
GO 10

बेशक, यह ब्लॉक में किसी भी काउंटर चर को रीसेट करेगा, इसलिए आपको इसे WHILEलूप या लूप के खिलाफ तौलना होगा x: ... GOTO x

  1. SELECT TOP ... FROM systypes

पॉल के ऊपर एक ही सवाल से, अनुज त्रिपाठी ने निम्नलिखित चाल का उपयोग किया :

SELECT TOP 10 REPLICATE('*',10) FROM systypes

या, जैसा कि टिप्पणियों में pinkfloydx33 द्वारा सुझाया गया है:

SELECT TOP 10'**********'FROM systypes

ध्यान दें कि यह किसी भी वास्तविक सामग्री पर निर्भर नहीं करता है systypes, बस सिस्टम व्यू मौजूद है (जो कि यह प्रत्येक MS SQL डेटाबेस में है), और इसमें कम से कम 10 पंक्तियाँ हैं (यह SQL के अधिकांश हाल के संस्करणों के लिए 34 को समाहित करता है) )। मुझे छोटे नामों के साथ कोई सिस्टम दृश्य नहीं मिला (जिसके लिए sys.उपसर्ग की आवश्यकता नहीं थी ), इसलिए यह आदर्श हो सकता है।


1

STRING_SPLIT परिणाम में संख्या स्तंभ जोड़ने के लिए कुछ दिलचस्प विचारों के लिए dba.stackexchange पर यह प्रश्न देखें ।

एक स्ट्रिंग की तरह 'one,two,three,four,five', हम कुछ प्राप्त करना चाहते हैं:

value   n
------ ---
one     1
two     2
three   3
four    4
five    5
  1. प्रति या स्थिरांक ROW_NUMBER()द्वारा जो ओबिश का उत्तर, उपयोग और आदेश NULL:

    SELECT value, ROW_NUMBER() OVER(ORDER BY (SELECT 1))n
    FROM STRING_SPLIT('one,two,three,four,five',',')
    
  2. पॉल व्हाइट के जवाब के अनुसार, एक का उपयोग करेंSEQUENCE :

    CREATE SEQUENCE s START WITH 1
    SELECT value, NEXT VALUE FOR s 
    FROM STRING_SPLIT('one,two,three,four,five', ',')
    

अनुक्रम दिलचस्प लगातार वस्तुएं हैं; आप डेटा प्रकार, न्यूनतम और अधिकतम मान, अंतराल को परिभाषित कर सकते हैं, और क्या यह शुरुआत के आसपास रहता है:

    CREATE SEQUENCE s TINYINT;     --Starts at 0
    CREATE SEQUENCE s MINVALUE 1;  --Shorter than START WITH
    SELECT NEXT VALUE FOR s        --Retrieves the next value from the sequence
    ALTER SEQUENCE s RESTART;      --Restarts a sequence to its original start value
  1. प्रति बीजू जोस का जवाब है, तो आप उपयोग कर सकते हैं समारोह (जो नहीं के रूप में हीIDENTITY() IDENTITY संपत्ति एक सम्मिलित करें के साथ संयोजन के रूप में:

    SELECT value v,IDENTITY(INT) AS n
    INTO t
    FROM STRING_SPLIT('one,two,three,four,five',',')
    
    SELECT * FROM t
    

ध्यान दें कि अंतिम दो पैरामीटर IDENTITY(INT,1,1)वैकल्पिक हैं, और बाहर किए जाने पर 1 में डिफ़ॉल्ट हो जाएगा।


समस्या यह है कि STRING_SPLIT किसी भी रिटर्न ऑर्डर की गारंटी नहीं देता है। आपको लगता है कि यह हमेशा स्ट्रिंग को मूल स्ट्रिंग में टोकन के क्रम में लौटाएगा। वास्तव में यह भी हो सकता है! हालाँकि, डॉक्स में कोई गारंटी नहीं है। यदि आप आदेश की परवाह नहीं करते हैं तो यह ठीक है। लेकिन अगर आप करते हैं (जैसे CSV प्रारूप में एक पंक्ति पार्स करना), तो एक समस्या है।
14:14 पर user1443098

1
@ user1443098 मैं अंततः आपके साथ एक व्यावसायिक उद्देश्य के लिए कोड की सिफारिश करने के संदर्भ में सहमत हूं, जैसा कि हम देख सकते हैं। लेकिन पीपीसीजी पर चुनौतियों के लिए मेरे मानक थोड़े अलग हैं; अगर मैं चाहता हूं कि आदेश में मेरे कोड रिटर्न पंक्तियों का परीक्षण कर रहा हूं तो मैं बाइट्स को बचाऊंगा जहां मैं कर सकता हूं। ORDER BYअगर मैं इससे दूर हो जाऊं तो मैं कैसे बाहर जाऊंगा , इसी तरह (उदाहरण के लिए , टोस्ट , बर्न्ट, ब्रुली के लिए मेरा जवाब देखें )।
ब्रैडेक

1

बस पता चला है कि उद्धरणों को समाप्त करने के लिएREPLACE आप एकल-वर्ण के लिए अंकों का उपयोग कर सकते हैं :

--44 bytes
PRINT REPLACE('Baby Shark******','*',' doo')

--42 bytes
PRINT REPLACE('Baby Shark000000',0,' doo')

ऐसा इसलिए है क्योंकि REPLACEस्ट्रिंग के लिए एक अंतर्निहित रूपांतरण है।

दोनों एक ही आउटपुट का उत्पादन करते हैं:

Baby Shark doo doo doo doo doo doo

0

_ और # वैध उपनाम हैं। मैं उन्हें यह दिखाने के लिए कि यह रिटर्न से क्लॉज उदा

SELECT TOP 10 number, n2
FROM master.dbo.spt_values v
CROSS APPLY (SELECT number*2 n2) _

मुझे यह पसंद है जब CROSS APPLY का एकमात्र उद्देश्य एक अभिव्यक्ति की गणना करना है।

उस मामले के लिए, उप-अभिव्यक्तियों की गणना के लिए APPLY का उपयोग करना आपके कोड DRY-er (और कम) बनाने का एक अच्छा तरीका है। मैंने निष्पादन योजनाओं में जो देखा है, उसमें इस दृष्टिकोण के लिए कोई अतिरिक्त लागत नहीं है। संकलक यह पता लगा रहे हैं कि आप केवल किसी चीज़ की गणना कर रहे हैं और इसे किसी अन्य अभिव्यक्ति की तरह मानते हैं।


मुझे लगता है कि क्रॉस अप्लाई लंबे समय तक होता है, किसी अन्य छोटी विधि को
खोजे

ठीक है - ऊपर दिए गए उदाहरण को छोटा करें!
user1443098 13

शीर्ष 10 नंबर का चयन करें, नंबर * 2 n2 मास्टर से ..dpt.values ​​v
Select master.dbo.spt_values

मेरा मतलब है, ज्वाइन करते रहना। वैसे, जब आप एक बार xml क्वेरीज़ बनाते हैं, तो CROSS APPLY इसे करने का एकमात्र तरीका बन सकता है, क्योंकि हो सकता है कि सब-वे में कोई कॉलम शामिल न हो।
user1443098

सबसील क्रॉस क्रॉस से कम है: सेलेक्ट टॉप 10 * FROM (सेलेक्ट नंबर n, नंबर * 2n2 FROM मास्टर..spt_values) x
t-clausen.dk 5'19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.