답변:
내 일반적인 속임수 가방 ::
@
t-sql에서 유효한 변수입니다.iif
는 VB 스타일 사례를 추가 했습니다. 이것은 거의 항상 동등한 것보다 짧다 if
else
.\
돈 유형에서 숫자를 0으로 초기화하는 유용한 방법입니다. 을 추가하여 값을 부동 소수점으로 변환 할 수 있습니다 e
. 예를 들어 4e
또는 \k
k를 0.00 돈으로 설정합니다.rCTE
100 개 미만의 숫자 표를 만드는 가장 좋은 방법 인 것 같습니다. spt_values를 사용하는 것보다 짧습니다. 100 개 이상이 필요한 경우 교차 결합하여 추가하십시오.+=
다른 복합 연산자는 2008 년에 추가되었습니다.이 연산자를 사용하면 몇 문자를 절약 할 수 있습니다.;
.Select*from A,B where condition
보다 짧다select*from A join b on condition
goto
루프 로 다시 작성하는 것이 가장 좋습니다 .STR()
int를 문자열로 바꾸는 가장 짧은 함수입니다. 둘 이상의 변환을 수행하거나 수많은 다른 데이터 유형을 연결해야하는 경우 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
테이블 또는 하위 쿼리를 만드는 데 사용할 수 있습니다 . 상수 행이 몇 개 필요한 경우에만 실제로 이점이 있습니다.
SQL을 사용한 코드 압축
SQL은 말이 많고 점수가 높으며 우리가 좋아하는만큼 SELECT FROM WHERE
사용할 때마다 23 바이트가 소요됩니다. 이 단어와 다른 반복 단어 또는 전체 코드 스 니펫을 압축 할 수 있습니다. 이렇게하면 반복되는 코드의 한계 비용이 1 바이트로 줄어 듭니다! *
작동 원리 :
문제 :
선결제 비용은 100 바이트에 가깝고 교체 테이블의 각 행에는 6 바이트가 추가로 소요됩니다. 이러한 종류의 논리는 정리할 수없는 많은 코드로 작업하지 않거나 문제가 압축 기반 인 경우가 아니면 효과적이지 않습니다.
여기에 예가 있습니다
도전 과제는 2, 3 및 5의 마지막 10 배수를 n으로 만드는 것입니다. 이 ( 343 bytes golfed )가 내가 생각해 낼 수있는 최고의 솔루션 이라고 가정 해 봅시다 .
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)
SELECT @=REPLACE(@,i,j)FROM(VALUES(...)x(i,j)
있는 경우 LEFT()
and과 단일 열을 사용 하는 대신 바이트 수를 절약 할 수있는 것으로 확인되었습니다 SUBSTRING()
. 8 개 이상인 경우 추가 따옴표와 쉼표를 피하는 것이 좋습니다.
SET @=REPLACE(REPLACE(REPLACE(...
재미있는 것이 있습니다. 이것은 열의 값을 단일 튜플로 변환합니다.
편집 : 의견 주셔서 감사합니다. XML 태그없이 롤업하는 가장 짧은 방법은 다음과 같습니다.
SELECT (SELECT column1+''
FROM table
ORDER BY column1
FOR XML PATH(''))
참고 : XML이 유효한 출력 인 경우 외부 선택 및 구문 분석을 생략 할 수 있습니다. 또한, column1+''
문자열에서만 작동합니다. 숫자 유형의 경우 가장 좋습니다column1+0
<column_name>value1</column_name><column_name>value2</column_name>...
합니다. 열에서 CSV를 DECLARE @ VARCHAR(MAX)='';SELECT @+=column_name+',' FROM table_name;SELECT @
얻으 려면 @MichaelB의 첫 번째 팁 덕분에을 반환 할 수 value1,value2,...
있습니다. 그러나 실제로는 XML 트릭보다 9 자 더 깁니다. (
Ltrim
select (xml path ( '')의 경우 select ...)가을 반환하므로 필요하지 않습니다 nvarchar(max)
. 또한 열을 해결하려면 비 돌연변이 식을 사용하십시오. 숫자의 v+0
경우 문자열에 빈 문자열 등을 추가 할 수 있습니다 .이 골프 팁을 실제로 고려하지는 않지만 SQL 서버에서 쿼리를 작성하는 방법은 슬프게도 현실입니다.
Michael B는 숫자 테이블에 재귀 적 CTE를 사용한다고 언급 했지만 예제는 보여주지 않았습니다. 다음은 이 다른 스레드에서 해결 한 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
따라서 SQL 2016은 COMPRESS
함수 (및 DECOMPRESS
함수)를 추가 하여 문자열 또는 이진을 GZIP 할 수있는 기능을 추가했습니다.
문제는 골프를 위해 이것을 이용하는 방법을 즉시 알 수 없다는 것입니다. COMPRESS
는 문자열을 사용할 수 있지만 바이트를VARBINARY
짧게 (SQL 필드에 저장 한 경우 ) 짧지 만 문자 가 더 긴 (16 진수)을 반환합니다 .VARBINARY
나는 전에 이것을 가지고 놀았지만 마침내 SO 에 대한 이 오래된 대답을 기반으로 작동하는 버전을 만들 수있었습니다 . 이 게시물은 새로운 GZIP 함수를 사용하지 않지만 a VARBINARY
를 Base-64 인코딩 문자열 로 변환 합니다. 우리는 새로운 기능을 올바른 장소에 삽입하고 약간 골프화해야했습니다.
매우 긴 문자열을 Base-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)
하고 inner에 저장할 수 있습니다 CAST
.
DECLARE @ XML='encoded_string_here'
SELECT CONCAT('',DECOMPRESS(@.value('.','varbinary(max)')))
이것은 그 자체 로 약간 더 길지만 다른 이유로 변수에 필요한 경우 도움이 될 수 있습니다.
도전 과제를위한 테이블 생성 및 사용에 대한 몇 가지 생각 :
1. 기존 테이블을 통해 SQL 입력 가능
SQL은 명명 된 테이블에서 입력을받을 수 있습니다.
입력 값으로이 테이블을 생성하고 채우는 것은 총 바이트 수에 포함되지 않으며 이미 존재한다고 가정 할 수 있습니다.
즉, 입력 테이블에서 간단한 SELECT를 통해 계산을 출력 할 수 있습니다.
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. 가능하면 SELECT INTO를 사용하여 테이블을 작성하십시오.
(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 개 이하의 행으로 짧아지고 하단 버전 (왼쪽 및 SUBSTRING으로 인해)이 8 개 이상의 행으로 짧아집니다 . 정확한 데이터에 따라 마일리지가 다를 수 있습니다.
5 : 매우 긴 텍스트 시퀀스에 REPLACE 및 EXEC 사용
편안하게 drei의 탁월한 대답의 맥락에서 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 : 여러 변수 대신 명명 된 열이있는 SELECT를 사용하십시오.
jmlt의 훌륭한 답변 here 에서 영감을 얻어 SELECT를 통해 문자열을 재사용 하십시오 .
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
(MS SQL의 경우 \t
인라인 리턴으로 변경 하고 바이트 저장으로 변경 CONCAT()
했습니다 +
).
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
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}', '[]{}', '()()');
두 번째 문자열의 각 문자는 세 번째 문자열의 해당 문자 로 바뀝니다 .
우리는 다음과 같은 것으로 많은 캐릭터를 제거 할 수있는 것처럼 보입니다. REPLACE(TRANSLATE('source string','ABCD','XXXX'),'X','')
뿐만 아니라, 같은 일부 더 흥미로운 것들 CONCAT_WS
과 STRING_AGG
뿐만 아니라 아마 가치 모양이다.
거룩한 암소, 나는 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
.
내가 보았고 보존하고 싶었던 몇 가지 더 관련이없는 트릭 :
GO #
특정 횟수만큼 블록을 반복하는 데 사용 합니다 .바울의 탁월한 대답 에서이 영리한 속임수를 보았습니다 .
PRINT'**********'
GO 10
물론 이것은 블록의 카운터 변수를 재설정하므로 WHILE
루프 또는 루프 에 대해 무게를 측정해야합니다 x: ... GOTO x
.
SELECT TOP ... FROM systypes
Paul의 위와 같은 질문에서 Anuj Tripathi는 다음과 같은 트릭을 사용했습니다 .
SELECT TOP 10 REPLICATE('*',10) FROM systypes
또는 의견에서 pinkfloydx33이 제안한대로 :
SELECT TOP 10'**********'FROM systypes
이것은 모든 실제 SQL 내용 에 의존하지 않으며 systypes
시스템 뷰가 존재하고 (모든 MS SQL 데이터베이스에 있음) 최소 10 개의 행 (최신 버전의 SQL의 경우 34를 포함하는 것으로 보입니다) ). 이름이 짧은 시스템 sys.
접두사를 찾을 수 없으므로 ( 접두사가 필요하지 않음 ) 이상적입니다.
STRING_SPLIT 결과에 숫자 열을 추가하는 데 대한 흥미로운 아이디어는 dba.stackexchange에서이 질문을 참조하십시오 .
같은 문자열이 주어지면 'one,two,three,four,five'
다음과 같은 것을 얻고 싶습니다.
value n
------ ---
one 1
two 2
three 3
four 4
five 5
Joe Obbish의 답변, 사용 ROW_NUMBER()
및 순서 NULL
또는 상수 :
SELECT value, ROW_NUMBER() OVER(ORDER BY (SELECT 1))n
FROM STRING_SPLIT('one,two,three,four,five',',')
Paul White의 답변에 따라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
비주 호세의 대답은 당, 당신이 사용할 수있는 기능 입니다 ( 하지 와 같은 특성 은 INSERT와 함께를 :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입니다.
ORDER BY
내가 도망 갈 수 있는 방법과 비슷한 방법과 비슷 합니다 ( 예 : Toasty, Burnt, Brulee 에 대한 답변 참조 ).
_ 및 #은 유효한 별칭입니다. CROSS APPLY와 함께 사용하여 반환되는 열이 FROM 절의 일부인 것처럼 보이게합니다.
SELECT TOP 10 number, n2
FROM master.dbo.spt_values v
CROSS APPLY (SELECT number*2 n2) _
CROSS APPLY의 유일한 목적이 표현식을 계산하는 것이라면 이것을 좋아합니다.
이를 위해, 서브 표현식 계산에 APPLY를 사용하는 것은 코드를 DRY-er (및 더 짧게) 만드는 깔끔한 방법입니다. 실행 계획에서 본 것으로부터이 접근 방식에는 추가 비용이 없습니다. 컴파일러는 단지 무언가를 계산하고 다른 표현식처럼 취급한다는 것을 알아냅니다.