TSQL: Как объединить два значения (money / int) с помощью UNION ALL без изменения данных? - PullRequest
0 голосов
/ 04 марта 2011

У меня следующий запрос:

create table #Result (Reward varchar(40), Value MONEY);

insert #Result exec GetCurrentCycleQualifierStatusByAccountId @AccountId=76011;

with cteFirstResults as
(select Reward, round(Value,2) as Value from #Result where Reward like '%Balance%'), 
cteSecondResults as
(select Reward, convert(INTEGER, Value) as Value from #Result where Reward NOT like    '%Balance%')

select * from cteFirstResults 
UNION ALL
select * from cteSecondResults;

drop table #Result;

Когда я запускаю команду select * индивидуально для каждой таблицы "cte", я получаю нужные результаты.
Но когда все запускается вместе, я получаю что-тонапример:

Reward          Value
------          -----
Daily Balance   4709.00
Value A         1.00
Value B         9.00

Я хочу, чтобы данные Value A / Value B отображались без каких-либо десятичных значений, как это происходит при непосредственном выполнении выбора для таблицы.Как объединить два запроса в один, чтобы правильно отобразить эти данные?

Round (значение 0) ничего не делает.

Я не могу изменить sproc, из которого я собираю данные, но я могу сделать временную таблицу любым удобным для меня способом.

Спасибо,

Джейсон

Решение:

create table #Result (Reward varchar(40), Value MONEY);
insert #Result exec GetCurrentCycleQualifierStatusByAccountId @AccountId=76011;
With cteFirstResults as
(
Select Reward, Value
From #Result 
Where Reward like '%Balance%'
)
,  cteSecondResults as
(
Select Reward, cast(Value as int) as Value
From #Result 
Where Reward Not like '%Balance%'
)
Select Reward, Cast( Value As varchar(max)) As Value
From cteFirstResults 
Union All
Select Reward, Cast( value As varchar(max)) as Value
From cteSecondResults;
drop table #Result;

Ответы [ 3 ]

0 голосов
/ 04 марта 2011

Проблема в том, что целые числа неявно приводятся к десятичному числу, потому что они представлены в десятичном столбце.

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

    CREATE TABLE #test
(
    test decimal(9,2)
)

CREATE TABLE #test2
(
test int
)

INSERT INTO #test (test)
SELECT 1.25 UNION ALL
SELECT 172813.99

INSERT INTO #test2 (test)
SELECT 134 UNION ALL
SELECT 41

SELECT CAST(test as  varchar(max)) FROM #Test
UNION ALL
SELECT CAST(test as  varchar(max)) FROM #Test2

Результаты:

1.25
172813.99
134
41
0 голосов
/ 04 марта 2011

Каждый столбец Sql Server может иметь только 1 тип данных.

  • раунд (деньги, 4) возвращает деньги (4) *
  • convert (int) возвращает int

На основе приоритет типа данных

  • # 13. деньги
  • # 16. INT

Результирующий столбец деньги (4). Поэтому ВСЕ значения в столбце будут отформатированы с использованием money (4).

Ваши варианты

  1. конвертировать (плавать) в обе стороны - недостаток: значение 1.1 отображается как 1.1, а не 1.10
  2. convert (varchar) - вы заявили, что не хотите этого, и он меняет тип данных на принимающую программу

FWIW

Round (значение 0) ничего не делает.

Он делает что-то делает. Он сжигает процессор, округляя значение int до другого значения int (того же значения). Кстати, результирующий тип (все еще) "int". Это не имеет ничего общего с форматированием.

REF:

declare @m money
set @m = 12.3233
select SQL_VARIANT_PROPERTY(round(@m,2), 'basetype')   -- money
select SQL_VARIANT_PROPERTY(round(@m,2), 'precision')  -- 19
select SQL_VARIANT_PROPERTY(round(@m,2), 'scale')      -- 4
0 голосов
/ 04 марта 2011

В объединении SQL Server будет предполагать, что тип данных второго выбора совпадает с первым, и где он может их преобразовать, сделайте это.Вам придется побить его в своей собственной игре, и у вас есть собственное преобразование

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

...