I have two lines of script:
IIF (name.value ='no', name1.value, name2.Value) as [name 1],
IIF (name.value ='yes', name3.value, name4.value) as [name 1.5],
which gives me an output that once in SSRS I combine into one field in a table by using this expression:
=IIF(Fields!name_1.Value is nothing, Fields!name_1_5.Value, Fields!name_1.Value)
However, instead of using this fairly clumsy expression I'd like to rewrite the T-SQL above to bring the data through there, rather than muddle around in SSRS. Is there a way the two lines of script above can be nested to give me the same output I achieve via the expression in SSRS?
Any help gratefully received.
Many thanks.
Use COALESCE to return the first non-null value, like this:
SELECT
COALESCE(
IIF (name.value ='no', name1.value, name2.Value),
IIF (name.value ='yes', name3.value, name4.value)
) as [name 1 or 1.5]
FROM MyTable
Related
I have two functions, qdgc_getlonlat and qdgc_getrecursivestring, which separately return a string. I am now creating a new function where the goal is concatenate the results from the said functions. This is where I am now:
return query
select *
from qdgc_getlonlat(lon_value,lat_value)
union distinct
select *
from qdgc_getrecursivestring(lon_value,lat_value,depthlevel,'');
Unfortunately it returns an array which look slike this:
Not too bad, but I would like the functions to be returned as a concatenated text string like this:
E007S05BDCA
How can I do this?
Why not simply concatenate them?
SELECT
qdgc_getlonlat(lon_value,lat_value) || qdgc_getrecursivestring(lon_value,lat_value,depthlevel,'')
FROM
mytable
I use this sql to execute sql:
v_sql4 :='
INSERT INTO public.rebatesys(head,contract_no,history_no,f_sin,line_no,s_line_no,departmentcd,catagorycd,jan,seriescd,f_exclude, f_del,ins_date,ins_time,ins_user_id,ins_func_id,ins_ope_id,upd_date,upd_time,upd_user_id,upd_func_id,upd_ope_id)
VALUES (0, '''||v_contract_no||''', '||v_history_no||',1, '||v_line_no||', '||v_down_s_line_no||', '||coalesce(v_deptCD,null)||', '||0||', '''||v_singleJan||''','''||0||''','||v_fExclude||',
0, current_date, current_time, '||v_ins_user_id||', 0, 0,
current_date,current_time,'||v_upd_user_id||',0, 0);';
RAISE NOTICE 'v_sql4 IS : %', v_sql4;
EXECUTE v_sql4;
But when field "v_deptCD" is null,the whole sql is null,even I use coalesce,I still can't do id, the out put is :
NOTICE: v_sql4 IS : <NULL>
How to fix it?
When v_deptCD is null, you want to replace it by the string 'null', not the keyword.
', '||coalesce(v_deptCD,'null')||', '
You can use this
case when v_deptCD notnull then v_deptCD else null end
or use this for string concatination inside sql
concat(field1, ', ', field2)
Alternative approach to JGH solution is to use function format(your_string, list, of, values), it can ignore NULL values, but has the option to display them as NULL if you use %L in your format string. It will however single quote numbers if you use that format specifier, requiring casting in some cases.
Format arguments according to a format string. This function is similar to the C function sprintf. See Section 9.4.1.
But in my opinion best solution is to use USING clause and pass values in there. It looks kinda like prepared statement, protects you from SQL Injection, but does not cache plans like prepared statements. There are simple examples on how to do this in documentation for executing dynamic commands.
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2'
INTO c
USING checked_user, checked_date;
How can I use tSQL to find a string, and if it exists, return everything before that string?
i.e. in the example below, in an ETL process, how would we take the column from source, identify the string ?uniquecode= and therefore remove that, and everything else after it, in the SELECT statement for the sink column?
How can I best modify this tSQL statement below to return the values in SinkPageURL column above?
SELECT SourcePageURL FROM ExampleTable
I have attempted a Fiddle here - http://sqlfiddle.com/#!18/3b60a/4 using the below statement. It is disregarding the values where '?uniquecode=' does not exist though, and also leaves the '?' symbol. Need this to work with MS SQL Server '17.
Somewhat close, but no cigar. Help appreciated!
SELECT LEFT(SourcePageURL, CHARINDEX('?uniquecode=', SourcePageURL)) FROM sql_test
Try this query:
SELECT
CASE WHEN CHARINDEX('?uniquecode=', SourcePageURL) > 0
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
ELSE SourcePageURL END AS new_source
FROM sql_test;
If you instead wanted to update the source URLs in your example using this logic, you could try the following:
UPDATE sql_test
SET SourcePageURL = SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
WHERE SourcePageURL LIKE '%?uniquecode=%';
What is the argument type for the order by clause in Postgresql?
I came across a very strange behaviour (using Postgresql 9.5). Namely, the query
select * from unnest(array[1,4,3,2]) as x order by 1;
produces 1,2,3,4 as expected. However the query
select * from unnest(array[1,4,3,2]) as x order by 1::int;
produces 1,4,3,2, which seems strange. Similarly, whenever I replace 1::int with whatever function (e.g. greatest(0,1)) or even case operator, the results are unordered (on the contrary to what I would expect).
So which type should an argument of order by have, and how do I get the expected behaviour?
This is expected (and documented) behaviour:
A sort_expression can also be the column label or number of an output column
So the expression:
order by 1
sorts by the first column of the result set (as defined by the SQL standard)
However the expression:
order by 1::int
sorts by the constant value 1, it's essentially the same as:
order by 'foo'
By using a constant value for the order by all rows have the same sort value and thus aren't really sorted.
To sort by an expression, just use that:
order by
case
when some_column = 'foo' then 1
when some_column = 'bar' then 2
else 3
end
The above sorts the result based on the result of the case expression.
Actually I have a function with an integer argument which indicates the column to be used in the order by clause.
In a case when all columns are of the same type, this can work: :
SELECT ....
ORDER BY
CASE function_to_get_a_column_number()
WHEN 1 THEN column1
WHEN 2 THEN column2
.....
WHEN 1235 THEN column1235
END
If columns are of different types, you can try:
SELECT ....
ORDER BY
CASE function_to_get_a_column_number()
WHEN 1 THEN column1::varchar
WHEN 2 THEN column2::varchar
.....
WHEN 1235 THEN column1235::varchar
END
But these "workarounds" are horrible. You need some other approach than the function returning a column number.
Maybe a dynamic SQL ?
I would say that dynamic SQL (thanks #kordirko and the others for the hints) is the best solution to the problem I originally had in mind:
create temp table my_data (
id serial,
val text
);
insert into my_data(id, val)
values (default, 'a'), (default, 'c'), (default, 'd'), (default, 'b');
create function fetch_my_data(col text)
returns setof my_data as
$f$
begin
return query execute $$
select * from my_data
order by $$|| quote_ident(col);
end
$f$ language plpgsql;
select * from fetch_my_data('val'); -- order by val
select * from fetch_my_data('id'); -- order by id
In the beginning I thought this could be achieved using case expression in the argument of the order by clause - the sort_expression. And here comes the tricky part which confused me: when sort_expression is a kind of identifier (name of a column or a number of a column), the corresponding column is used when ordering the results. But when sort_expression is some value, we actually order the results using that value itself (computed for each row). This is #a_horse_with_no_name's answer rephrased.
So when I queried ... order by 1::int, in a way I have assigned value 1 to each row and then tried to sort an array of ones, which clearly is useless.
There are some workarounds without dynamic queries, but they require writing more code and do not seem to have any significant advantages.
I'm a SSAS newbie and i'm trying to query a cube to retrieve data against aome measure groups order by date. The date range i wish to specify in my query. The query I'm using is this:-
SELECT
{
[Measures].[Measure1],
[Measures].[Measure2],
[Measures].[Measure3]
}
ON COLUMNS,
NON EMPTY{
[Date].[AllMembers]
}
ON ROWS
FROM (SELECT ( STRTOMEMBER('2/23/2013', CONSTRAINED) :
STRTOMEMBER('3/1/2013', CONSTRAINED) ) ON COLUMNS
FROM [MyCube])
However it gives me the following error
Query (10, 16) The restrictions imposed by the CONSTRAINED flag in the STRTOMEMBER function were violated.
I tried removing the constrained keyword and then even strtomember function. But in each cases i got the following errors respectively
Query (10, 16) The STRTOMEMBER function expects a member expression for the 1 argument. A string or numeric expression was used.
and
*Query (10, 14) The : function expects a member expression for the 1 argument. A string or numeric expression was used.
*
I can understand from the last two errors that i need to include the constraint keyword. But can anyone tell me why this query wont execute?
The string that you pass as the member expression must be a fully-qualified member name, or resolve to one. Use the same format as you did in the SELECT.
For example:
STRTOMEMBER('[Date].[2/23/2013]', CONSTRAINED)
Edit: I just noticed the syntax of your range select looks wrong -- you need to use {...}, not (...).
SELECT {
STRTOMEMBER('2/23/2013', CONSTRAINED) :
STRTOMEMBER('3/1/2013', CONSTRAINED) }
Please execute below script.
Extract your date dimension attribute copy it by right clicking and paste it in STRTOMEMBER value.
It will works fine.
SELECT NON EMPTY { [Measures].[Internet Sales Amount] } ON COLUMNS
FROM ( SELECT ( STRTOMEMBER('[Date].[Date].&[20050701]') :
STRTOMEMBER('[Date].[Date].&[20061007]') ) ON COLUMNS
FROM [Adventure Works])
FROM ( SELECT (
STRTOMEMBER(#FromDateCalendarDate, CONSTRAINED) :
STRTOMEMBER(#ToDateCalendarDate, CONSTRAINED) ) ON COLUMNS