Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Выравнивание значений  [new]
Caxa_ASS
Member

Откуда:
Сообщений: 96
Всем привет.

Как выровнять все значения столбца в таблице или по левому краю или по правому? Тип данных в столбце - bigint.
17 май 21, 01:12    [22322916]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37254
Столбцы -- в экселе. В MSSQL -- поля, и у них нет краев, ни левых, ни правых.
17 май 21, 01:41    [22322921]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
aleks222
Member

Откуда:
Сообщений: 1416
Гавриленко Сергей Алексеевич
Столбцы -- в экселе. В MSSQL -- поля, и у них нет краев, ни левых, ни правых.

Не, ну неправда ваша.
Края там, конечно, есть. LTRIM и RTRIM тому свидетели.
Только вот выравнивать сервер не умеет.
Клинтское это дело...
17 май 21, 07:07    [22322938]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21184
aleks222
Края там, конечно, есть. LTRIM и RTRIM тому свидетели.
Края есть, когда дело доходит до отображения данных, на экране или там при печати. Но этим занимается вовсе не сервер, а используемый клиент. Так что края, конечно, есть - но не "там".
17 май 21, 08:46    [22322953]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
aleks222
Member

Откуда:
Сообщений: 1416
Akina
aleks222
Края там, конечно, есть. LTRIM и RTRIM тому свидетели.
Края есть, когда дело доходит до отображения данных, на экране или там при печати. Но этим занимается вовсе не сервер, а используемый клиент. Так что края, конечно, есть - но не "там".

Ну, можно отрицать даже то, что земля круглаяесть LTRIM и RTRIM.
17 май 21, 09:38    [22322964]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21184
aleks222
можно отрицать даже то, что есть LTRIM и RTRIM.
Есть, есть... только они никакого отношения к выравниванию не имеют. Вот были бы LPAD/RPAD или соответствующие атрибуты у полей - они б ещё худо-бедно подошли.

Кстати, использование LTRIM/RTRIM ну никаким образом не заставит клиента прижать значение к левому или правому краю, хоть застрелись - у него для поля есть свойство xxx_justify, и чхать он хотел на всё. А грид или куда там оно выводится - так и вовсе не в курсе, какие в запросе были использованы функции.
17 май 21, 10:43    [22322992]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
iap
Member

Откуда: Москва
Сообщений: 47101
aleks222
Akina
пропущено...
Края есть, когда дело доходит до отображения данных, на экране или там при печати. Но этим занимается вовсе не сервер, а используемый клиент. Так что края, конечно, есть - но не "там".

Ну, можно отрицать даже то, что земля круглаяесть LTRIM и RTRIM.
Для типа BIGINT?
Всё равно же придётся преобразовывать в строку. Только для отображения.
17 май 21, 10:49    [22322995]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8701
тс явно промахнулся форумом, ему надо изучать язык средства написания клиентского приложения.
17 май 21, 10:53    [22322999]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
aleks222
Member

Откуда:
Сообщений: 1416
Akina
aleks222
можно отрицать даже то, что есть LTRIM и RTRIM.
Есть, есть... только они никакого отношения к выравниванию не имеют. Вот были бы LPAD/RPAD или соответствующие атрибуты у полей - они б ещё худо-бедно подошли.

Кстати, использование LTRIM/RTRIM ну никаким образом не заставит клиента прижать значение к левому или правому краю, хоть застрелись - у него для поля есть свойство xxx_justify, и чхать он хотел на всё. А грид или куда там оно выводится - так и вовсе не в курсе, какие в запросе были использованы функции.


Опять передергиваете.
Базар был за "края".
17 май 21, 15:14    [22323132]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
aleks222
Member

Откуда:
Сообщений: 1416
iap
aleks222
пропущено...

Ну, можно отрицать даже то, что земля круглаяесть LTRIM и RTRIM.
Для типа BIGINT?
Всё равно же придётся преобразовывать в строку. Только для отображения.

Первый бит - последний бит.
Ну, может и не края.
17 май 21, 15:16    [22323136]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4844
Гавриленко Сергей Алексеевич
Столбцы -- в экселе. В MSSQL -- поля, и у них нет краев, ни левых, ни правых.


Если время военное, то можно и значение синуса довести до 4 и столбцы выравнять по левому краю.

SELECT SUBSTRING(CONCAT(N, REPLICATE(' ', 20)), 1, 20) FROM 
(
	SELECT 1 AS N UNION ALL SELECT 22423423 UNION ALL SELECT -3333
) B
17 май 21, 17:58    [22323230]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
Осталось синус довести до 6:

declare @L int = 10;

SELECT SUBSTRING(CONCAT(N, REPLICATE(' ', 20)), 1, 20) -- по левому краю
      ,right(concat(replicate(' ', @L), N), @L)        -- по правому краю
      ,concat(replicate('.', (@L-len(N)) / 2), N, replicate('.', @L-len(N)-((@L-len(N)) / 2))) -- по центру

FROM 
(
	SELECT 1 AS N UNION ALL SELECT 22423423 UNION ALL SELECT -3333
) B

Результат по центру:

....1.....
.22423423.
..-3333...


Сообщение было отредактировано: 17 май 21, 20:10
17 май 21, 20:15    [22323320]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
aleks222
Member

Откуда:
Сообщений: 1416
Wlr-l
Осталось синус довести до 6:

declare @L int = 10;

SELECT SUBSTRING(CONCAT(N, REPLICATE(' ', 20)), 1, 20) -- по левому краю
      ,right(concat(replicate(' ', @L), N), @L)        -- по правому краю
      ,concat(replicate('.', (@L-len(N)) / 2), N, replicate('.', @L-len(N)-((@L-len(N)) / 2))) -- по центру

FROM 
(
	SELECT 1 AS N UNION ALL SELECT 22423423 UNION ALL SELECT -3333
) B

Результат по центру:

....1.....
.22423423.
..-3333...


Это позор.
https://docs.microsoft.com/ru-ru/sql/t-sql/functions/str-transact-sql?view=sql-server-ver15
17 май 21, 20:27    [22323330]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
aleks222,

Раз сказал А, скажи и В. Как str поможет выровнять строковое представление числа по центру?
17 май 21, 20:35    [22323334]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1933
Коллеги! Не ссорьтесь и вспомните про функцию format:

 use [AdventureWorks2014]
 GO
  SELECT TOP(5)CurrencyRateID, EndOfDayRate
              ,FORMAT(EndOfDayRate, 'N', 'en-us') AS 'EN-US Number Format'
              ,FORMAT(EndOfDayRate, 'G', 'en-us') AS 'EN-US General Format'
              ,FORMAT(EndOfDayRate, 'C', 'en-us') AS 'EN-US Currency Format'
			  ,FORMAT(EndOfDayRate, '000,000,000,000.00', 'en-us') AS 'EN-US Custom Format'
			  ,FORMAT(EndOfDayRate, '000,000,000,000.00', 'en-us') AS 'EN-US INTEGER Custom Format'
			   ,FORMAT(EndOfDayRate, 'N', 'ru-ru') AS 'RU-RU Number Format'
              ,FORMAT(EndOfDayRate, 'G', 'ru-ru') AS 'RU-RU General Format'
              ,FORMAT(EndOfDayRate, 'C', 'ru-ru') AS 'RU-RU Currency Format'
			  ,FORMAT(EndOfDayRate, '000,000,000,000.00', 'ru-ru') AS 'RU-RU Custom Format'
			  ,FORMAT(EndOfDayRate, '000,000,000,000.00', 'ru-ru') AS 'RU-RU INTEGER Custom Format'
			  ,FORMAT(EndOfDayRate*1000000, '####.00', 'ru-ru') AS 'RU-RU # Custom Format'
			  ,FORMAT(EndOfDayRate, '0.00%', 'ru-ru') AS 'RU-RU % Custom Format'
  FROM Sales.CurrencyRate
  ORDER BY CurrencyRateID;


Сервер 2014.
17 май 21, 21:01    [22323346]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
DaniilSeryi,

1.Здесь никто и не ссорится, решаем программистский этюд.

2.Вы не прочли условия задачи, поэтому привели способы форматирования чисел с помощью функции format, но задача-то стоит в эмуляции функций LPAD/RPAD (см. 22322992).

3.Вы не увеличили значение синуса, а уменьшили его.
18 май 21, 11:52    [22323496]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
Всю ночь не спал, всё думал, "как мне позор свой искупить"?

1.Выросло поколение программистов, которые не знают, и есть программисты, которые уже забыли, что такое текстовый режим отображения информации.

2.Задача выравнивания данных в запросе может быть вполне реальной, если нужно, например, подготовить файл для его печати на устройстве, которое а) поддерживает текстовый режим и б) в нем можно установить моноширинный шрифт.

3.Главное получить правильный результат, потом его можно улучшать до бесконечности.

4.Выравнивание по левому краю можно выполнить просто:
cast(N as char(10)),
но есть два но а) длину можно задать только константой; б) если нужно проверить результат, то после cast нужно еще заменить пробелы на точки: replace(cast(N as char(10)), ' ', '.'). Попробуйте сосчитать пробелы на экране или на белом листе бумаге, особенно при пропорциональном шрифте.

5.Выравнивание по правому краю целого числа можно выполнить функцией
str(N, @L [, 0]).
Здесь длину можно задать переменной, но а) для того, чтобы пробелы заменить на точки, нужна будет функция replace; б) нельзя выровнять НЕ целые числа и текст.

6. Осталось привести пример.
declare @L int = 10,
        @H char(1) = '.';

SELECT left(concat(N, replicate(@H, @L)), @L)     as L1 -- по левому краю
      ,replace(cast(N as char(10)), ' ', '.')     as L2
      ,right(concat(replicate(@H, @L), N), @L)    as R1 -- по правому краю
      ,replace(str(N, @L), ' ', @H)               as R2
      ,concat(replicate(@H, (@L-len(N)) / 2), N, replicate(@H, @L-len(N)-((@L-len(N)) / 2))) as C1 -- по центру
FROM 
(
	SELECT 1 AS N UNION ALL SELECT 22423423 UNION ALL SELECT -3333
) B


L1	        L2      	R1      	R2      	C1
1......... 1......... .........1 .........1 ....1.....
22423423.. 22423423.. ..22423423 ..22423423 .22423423.
-3333..... -3333..... .....-3333 .....-3333 ..-3333...

В L1 функция substring заменена функцию left для большей наглядности. Выражения L1, R1 C1, на мой взгляд, однотипны, подходят к данным любого типа и легко отлаживаются.
18 май 21, 12:07    [22323514]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1933
Wlr-l,

Ну так числа-то выровнены по длине, и более того - по обоим краям разом! :-)
18 май 21, 14:08    [22323619]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Caxa_ASS
Member

Откуда:
Сообщений: 96
Wlr-l, a_voronin, DaniilSeryi парни, огромное спасибо.

Wlr-l - спасибо за подробное описание и решение!
18 май 21, 14:23    [22323625]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
DaniilSeryi
Wlr-l,

Ну так числа-то выровнены по длине, и более того - по обоим краям разом! :-)


1.Вы не прочли условия задачи, поэтому привели способы форматирования чисел с помощью функции format, но задача-то стоит в эмуляции функций LPAD/RPAD (см. 22322992).
2.Надо понять, что же все-таки делают функции LPAD и RPAD, которых нет в T-SQL. Если непонятно, то можно взять текстовый редактор и посмотреть, как происходит выравнивание влево, вправо, по центру.
3.Если приводите какие-то примеры из документации, то нужно сначала самому их выполнить и осмыслить результат.
4.Разберем ваш пример, на примере одной культуры с выравниванием влево:
declare @L  int      = 10,
        @H  char(1)  = '.';
declare @HH char(20) = replicate(@H, @L);

declare @EndOfDayRate int = 12345;

select replace(FORMAT(@EndOfDayRate, 'N',          'ru-ru'), ' ', '.') AS 'Number'
      ,replace(FORMAT(@EndOfDayRate, 'G',          'ru-ru'), ' ', '.') AS 'General'
      ,replace(FORMAT(@EndOfDayRate, 'C',          'ru-ru'), ' ', '.') AS 'Currency'
      ,replace(FORMAT(@EndOfDayRate, '000,000.00', 'ru-ru'), ' ', '.') AS 'Custom'
      ,replace(FORMAT(@EndOfDayRate, '000,000.00', 'ru-ru'), ' ', '.') AS 'INT Custom'
      ,replace(FORMAT(@EndOfDayRate, '####.00',    'ru-ru'), ' ', '.') AS '# Custom'

      ,left(concat(@EndOfDayRate, @HH), @L)                            as L1


Number      General	Currency	Custom		INT Custom	# Custom	L1
12 345,00 12345 12 345,00.₽ 012 345,00 012 345,00 12345,00 12345.....

Сравните полученные результаты с эталоном L1. Увидели, что ни один из ваших примеров не решает поставленную задачу?

5.Вы не только уменьшили значение синуса, но и загнали его в отрицательную область.
18 май 21, 17:08    [22323743]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1933
Wlr-l,

блин, уже пошутить нельзя... Будьте немного проще, и разумные к Вам потянутся.
18 май 21, 17:16    [22323748]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
DaniilSeryi,

Я искренне рад, что вы поняли разницу между форматированием чисел и выравниванием полей, и что я не зря потратил время на эту задачу. Хоть какая-то польза получилась от меня. А тянуться ко мне не обязательно.


Безусловно функция format - полезная функция. Правда строка формата могла бы быть гибче. Например, можно было бы сделать 'N10.3' – под число отводится 10 позиций, из которых одна отводится под разделитель и три под дробную часть, незанятые позиции заполняются пробелами. Или, например, так 'S-12' – под строку отводится 12 символов, строка как есть прижимается влево (ведущие пробелы не удаляются). Если строка короче 12 символов, то она дополняется пробелами. Если длиннее, то обрезается. 'S12' – то же самое, только строка прижимается вправо. Если уж форматировать, то форматировать.

Конечно, можно свалить это на клиента с гридами и с чем-то там еще. Но часто такого клиента просто нет. Нужен обычный текстовый файл. При этом важно, чтобы механизмы выгрузки результата запроса в файл не вносили своих коррективов в форматирование выгружаемых данных.

Дополнение насчет краев: края хорошо поясняются наличием типов данных CHAR и VARCHAR.

Сообщение было отредактировано: 18 май 21, 19:36
18 май 21, 19:39    [22323807]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8701
Клиент эти пробелы тримнет и весь труд насмарку.
18 май 21, 23:35    [22323875]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Wlr-l
Member

Откуда:
Сообщений: 563
Владислав Колосов
Клиент эти пробелы тримнет и весь труд насмарку.


Посвящается всем тем, кто свято верит в то, что у строк и "полей" в T-SQL нет краев, что строки в T-SQL нельзя прижать к краям "поля", что все клиенты "тримят" пробелы.

1. "Столбцы -- в экселе. В MSSQL – поля".
Правило 1 Кодда: Вся информация в реляционной базе данных на логическом уровне должна быть явно представлена единственным способом: значениями в таблицах. Т.е. в MSSQL данные представлены в таблицах. Эксел тоже оперирует таблицами. Таблица, грубо говоря, – это строки и столбцы. Так в чем разница? В том, что, в одном случае, столбец называют полем, а другом случае, называют столбец столбцом? Действительно ли, что у столбца есть края, а у поля их нет?

2.Проведем эксперимент с краями текстового "поля".
Поскольку SQL Server это вещь в себе, будем общаться с ним на "настоящем" клиенте (я бы сказал самым настоящим из всех настоящих клиентов) SQL Server Management Studio (SSMS). Для эксперимента воспользуется запросом:
declare @c    char(5)      =  '  ab ',
        @v    varchar(5)   =  '  ab ',
        @cn   nchar(5)     = N'  ab ',
        @vn   nvarchar(5)  = N'  ab '

select replace(@c,  ' ', '.') as c,
       replace(@v,  ' ', '.') as v,
       replace(@cn, ' ', '.') as cn,
       replace(@vn, ' ', '.') as vn;

Задавая разные строки в этом запросе получим:

№	c	v	cn	vn
1 ..... ..... пустая строка
2 ..... . ..... . один пробел
3 ab... ab. ab... ab. пробел
4 ..ab. ..ab. ..ab. ..ab. пробел пробел a b пробел
5 ...ab ...ab ...ab ...ab пробел пробел пробел a b

Как видим, что CHAR не сохраняет справа пробелы исходной строки, а заполняет ими все отведенное для него пространство ("поле"), а VARCHAR сохраняет справа столько пробелов, сколько их есть в исходной строке.
Ни один из этих типов не удаляет и не добавляет пробелы слева в исходную строку.
Пятый пример демонстрирует прижатие строки 'ab' к правому краю "поля" (выравнивание справа).

Т.е. все происходит ожидаемо.

3.Следующий эксперимент. Данные из примера 4 (в строке есть пробелы слева и справа) выгрузим в файлы txt и csv.
Файл csv, если открыть его, например, Блокнотом, будет таким:
" ab ";" ab ";" ab ";" ab ",
а файл txt будет таким:
ab ab ab ab

Т.е. SQL Server, SSMS, файловая система Windows и Блокнот, взаимодействуя друг с другом, не изменили ни количество пробелов, ни их расположение в исходных данных.
Если SQL Server – это сервер, то SSMS, файловая система Windows и Блокнот – это типичные клиенты. Следовательно, не все клиенты "тримят" пробелы.
Комбинация клавиш Ctrl-C, Ctrl-V в SSMS не изменяет количество пробелов и их расположение. А эта же комбинация клавиш в Блокноте удаляет пробелы справа, т.е. выполняет операцию rtrim, но все остальные пробелы остаются на своих местах.

Можно для полноты счастья заархивировать эти файлы и послать по почте; получить их и разархивировать, потом распечатать, и убедиться, что все пробелы остались на своих местах. А ведь это тоже "клиенты".

Вывод, решая задачу нужно знать и использовать возможности имеющихся инструментальных средств. А можно сделать испуганные глаза и сказать, что все равно клиент (тот еще сферический конь в пальто) съест с таким трудом сформированные пробелы.

+
Вспомнился разговор на одном из совещаний по изменению документации:
- Так делать нельзя! Это противоречит приказу №ХХХ! – сказал подчиненный.
- А кто готовил этот приказ? – спросил недавно назначенный начальник.
- Мы!
- Так измените этот приказ!
- Мы не можем!
- А что вы можете?
- Отменить этот приказ и издать новый!
- Так сделайте это!


На этом у меня всё по этой теме. Всем удачи!
19 май 21, 17:53    [22324346]     Ответить | Цитировать Сообщить модератору
 Re: Выравнивание значений  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8701
Wlr-l,

не все клиенты почему, это зависит от настроения программиста. Если он для поля ввода или вывода указал свойство Trim, к примеру, то поступившие данные будут содержать пробелы, но при обновлении контрола или при сохранении пробелы будут усечены. Т.е. если "прокликать", то изображение может поползти. Поэтому надо предусматривать, что элемент управления, который отображает значение, настроен на желаемый вид центровки.
19 май 21, 18:42    [22324373]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить