Советы по игре в гольф в T-SQL


16

Какие общие советы у вас есть для игры в гольф в T-SQL? Я ищу идеи, которые могут быть применены к задачам по коду для гольфа в целом, которые хотя бы несколько специфичны для T-SQL. Пожалуйста, оставьте один совет за ответ.

Спасибо Marcog за оригинальную идею. :)


совет - используйте другой язык для игры в гольф. Sql ответы, как правило, получает очень мало или вообще не получает голосов.
t-clausen.dk

Ответы:


16

Моя общая сумка трюков ::

  • @ является допустимой переменной в t-sql.
  • В T-sql 2012 добавлено iifутверждение в стиле VB. Это почти всегда короче, чем эквивалент if else.
  • \полезный способ инициализировать число как 0 в денежном типе. Вы можете преобразовать значение в число с плавающей точкой, добавив e. например, 4eили \kкоторый установит k в значение 0,00 денег.
  • rCTEкажется, лучший способ создать таблицу чисел менее 100 записей. Даже короче, чем использование spt_values. Если вам нужно больше 100, перекрестное соединение и добавьте их.
  • += и другие составные операторы были добавлены в 2008 году. Используйте их, чтобы сохранить несколько символов.
  • Литералы обычно являются достаточно хорошим разделителем для псевдонимов. Вам редко нужен пробел или ;.
  • Используйте ANSI SQL соединения, если они вам нужны. Select*from A,B where conditionкороче чемselect*from A join b on condition
  • Если вы можете быть уверены, что ваш цикл while будет выполнять первую итерацию, лучше переписать его как gotoцикл стиля do- while.
  • 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для создания таблицы или подзапроса. Это будет действительно полезно, если вам нужно несколько постоянных строк.


Для меня $ немного более очевидно, чем \ для инициализации числа как 0 в денежном типе. YMMV
user1443098

5

Сжатие кода с использованием SQL

SQL многословен, имеет высокие оценки, и, сколько бы мы его ни любили, SELECT FROM WHEREстоит 23 байта при каждом использовании. Вы можете сжать эти и другие повторяющиеся слова или целые фрагменты кода. Это снизит предельную стоимость повторного кода до 1 байта! *

Как это работает:

  • Переменная объявляется и присваивается сжатый код SQL
  • Таблица изменяет переменную. Каждая строка выдает переменную.
  • Измененная переменная выполняется.

Проблема:

Предварительная стоимость составляет около 100 байтов, а каждая строка в таблице замены стоит еще 6 байтов. Такая логика не будет очень эффективной, если вы не работаете с большим количеством кода, который не можете урезать, или если задача основана на сжатии.

Вот пример

Задача состоит в том, чтобы получить последние 10 кратных 2,3 и 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)

Отличная стратегия, этот стиль с несколькими заменами может быть полезен и в более обычных сценариях.
BradC

1
После некоторого тестирования я определил, что если ваш список замен содержит 7 или меньше элементов, вы бы сэкономили байты, SELECT @=REPLACE(@,i,j)FROM(VALUES(...)x(i,j)вместо того чтобы использовать один столбец с LEFT()и SUBSTRING(). Если у вас есть 8 или более, то избегание лишних кавычек и запятых является хорошим компромиссом.
BradC

На самом деле для замены 4 или меньше, вы бы сэкономили байты со старомоднымSET @=REPLACE(REPLACE(REPLACE(...
BradC

4

Вот забавный Это преобразует значения в столбце в один кортеж.

РЕДАКТИРОВАТЬ: Спасибо за комментарии. Кажется, что самый короткий способ свернуть без тегов XML:

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

Примечание: если XML является допустимым выводом, вы можете опустить внешние select и parens. Кроме того column1+'', работает только для строк. Для чисел лучше всего делатьcolumn1+0


1
На самом деле это вернется <column_name>value1</column_name><column_name>value2</column_name>.... Чтобы получить CSV из столбца, вы можете DECLARE @ VARCHAR(MAX)='';SELECT @+=column_name+',' FROM table_name;SELECT @(спасибо за первый совет @ MichaelB), который вернется value1,value2,.... Однако на самом деле это на 9 символов длиннее вашего трюка с XML :(
Джейкоб

1
Обратите внимание, что вы можете сделать это короче. Ltrimне требуется, так как select (select ... для пути xml ('')) возвращает nvarchar(max). Кроме того, для решения этой проблемы просто используйте не мутирующее выражение. Для чисел, которые вы можете сделать v+0, для строки добавить пустую строку и т. Д. Хотя я не считаю это подсказкой для игры в гольф, это просто печальная реальность того, как писать запросы на сервере SQL.
Майкл Б

3

В T-SQL можно использовать несколько побитовых операторов .

У меня нет конкретного примера, но я считаю, что это полезный факт при игре в гольф на T-SQL.


1
Это очень актуально. Вместо того, чтобы писать условие типа x=0 or y=0, вы можете записать его как логически эквивалентный, x|y=0который экономит немало байтов!
Майкл Б


3

Научная запись - это более короткий метод для выражения очень больших и очень маленьких чисел, например, select 1000000000= select 1E9и select 0.000001= select 1E-6.


2

Майкл Б упомянул об использовании рекурсивного 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


2

Используйте сжатие GZIP для очень длинных строк!

Итак, я знал, что в SQL 2016 добавлена COMPRESSфункция (и DECOMPRESSфункция), которая (наконец-то) предоставляет возможность GZIP-строки или двоичного файла.

Проблема в том, что не сразу понятно, как воспользоваться этим для игры в гольф; COMPRESSможет принимать строку, но возвращает a VARBINARY, которое короче в байтах (при хранении в VARBINARYполе SQL ), но длиннее в символах (необработанный шестнадцатеричный код).

Я играл с этим раньше, но я наконец смог собрать рабочую версию, основанную на этом старом ответе на SO . Этот пост не использует новые функции GZIP, но он конвертирует в 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 :

Сохраните 10 байтов, изменив внешнее CASTна неявное преобразование, используя 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)')))

Это немного длиннее само по себе, но если вам нужно это в переменной по другим причинам, то это может помочь.


Хорошо, я не знаю SQL, но все равно это выглядит круто
MilkyWay90

1

Несколько мыслей о создании и использовании таблиц для испытаний:

1. Ввод SQL может быть выполнен через уже существующую таблицу

Code Golf Методы ввода / вывода :

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 или менее строками , нижняя версия (из-за LEFT и SUBSTRING) короче с 8 или более строками . Ваш пробег может варьироваться в зависимости от ваших точных данных.

5: используйте REPLACE и EXEC для очень длинных последовательностей текста

В отличном ответе comforblydrei , если у вас есть 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 здесь , повторно используйте строки через 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()на , +чтобы сохранить байты).


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 (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}', '[]{}', '()()');

Каждый символ во второй строке заменяется соответствующим символом в 3-й строке.

Похоже, мы могли бы устранить кучу персонажей с чем-то вроде 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 строк (это выглядит , чтобы содержать 34, для большинства последних версий SQL ). Я не смог найти никаких системных представлений с более короткими именами (которые не требовали sys.префикса), так что это может быть идеальным.


1

Смотрите этот вопрос на dba.stackexchange для некоторых интересных идей по добавлению числового столбца к результату STRING_SPLIT.

Учитывая строку как '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. За ответ Biju JOSE, вы можете использовать в 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), есть проблема.
user1443098

1
@ user1443098 В конечном счете, я согласен с вами в том, что касается рекомендации кода для бизнес-целей, как мы могли бы увидеть на dba.SE. Но для испытаний PPCG мои стандарты немного другие; если при тестировании мой код возвращает строки в нужном мне порядке, я сохраню байты там, где могу. Подобно тому, как я опущу, ORDER BYесли мне это сойдет с рук (см. Мой ответ, например, Toasty, Burnt, Brulee ).
BradC

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

_ и # являются действительными псевдонимами. Я использую их с CROSS APPLY, чтобы они выглядели как возвращаемые столбцы, как часть предложения FROM, например

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

Мне нравится, когда единственной целью CROSS APPLY является вычисление выражения.

В этом отношении использование APPLY для вычисления подвыражений - это отличный способ сделать ваш код более сухим (и более коротким). Из того, что я видел в планах выполнения, этот подход не требует дополнительных затрат. Компилятор выясняет, что вы просто что-то вычисляете, и обрабатывает это как любое другое выражение.


Я считаю, что перекрестное применение к длинному, действительно трудно найти полезную ситуацию, используя перекрестное применение, не найдя другого более короткого метода
t-clausen.dk

ОК - сокращайте пример, приведенный выше!
user1443098

ВЫБЕРИТЕ ТОП 10 номеров, число * 2 n2 ОТ master.dbo.spt_values ​​v
t-clausen.dk

Я имею в виду, сохраняя соединение. Кстати, после того, как вы создадите XML-запросы, CROSS APPLY может стать единственным способом сделать это, так как в подзапросе может не быть столбцов, для которых выполняется объединение.
user1443098

Подвыбор короче, чем перекрестное применение: ВЫБЕРИТЕ верхние 10 * ОТ (ВЫБЕРИТЕ номер n, номер * 2n2 ОТ master..spt_values) x
t-clausen.dk
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.