I have this query which takes in 3 parameters, StrParameter1 being the one which is key to what I'm trying to accomplish.
SELECT ai.strName,
ai.strId,
ai.lngBKey,
ci.strFormattedId,
ci.lngAKey,
ts.dtmPeriod,
ts.strT2Type,
ts.strImpact,
ts.curAmount,
ts.curBalance
FROM TBlCInfo ci,
tblAInfo ai,
tblTStage ts
WHERE ci.lngAKey = ai.lngAKey
AND ai.lngBKey = ts.lngBKey
AND ts.lngVersion = 0
AND ts.blnReversed = 0
AND ai.strType = #StrParameter1
AND ts.dtmPeriod >= #DtmParameter2
AND ts.dtmPeriod <= #DtmParameter3
I'd like to union this query with another, but only if StrParameter1 equals let's say, "AAAA". Otherwise, I only want the top portion of the query to fire. There's like 30 other circumstances where I would not need the union, but only 1 where it's needed.
Query 1
If StrParameter1 = 'AAAA' Then
UNION
QUERY 2
You can use below pattern to do what you are looking for
declare #param varchar(4) = 'AAAA'
select *
from MyTable
union
select *
from MyOtherTable
where #param = 'AAAA'
In this case if the #param is 'AAAA', the union will take in to place and if it is not, the second query will not return any result.
So this way you don't need to change your queries.
Related
How do I pick the first negative value row using CASE Statement? I do not want to use Where condition since it applies the condition to the entire data.
In the below sample, I just want to make the maximum of negative values (-469) to ABS(-469) which is 469 and leave the rest as is.
My MAX(CASE WHEN -469)...does not seem to work. Assume there is an ordering field.
Sample
------
1281
-469
-469
-509
-1359
-1359
-2759
-2829
CASE is no different from WHERE, it's checked against every row in your data (unless there is an index on this column). So the best I can think of is
UPDATE t
SET Sample = ABS(Sample)
WHERE Sample = (SELECT MAX(Sample) FROM t WHERE Sample < 0)
EDIT: just read that you actually need a "maximum of negatives", if you know what is that value, you can manually use CASE
SELECT CASE WHEN Sample = -469 THEN ABS(Sample) ELSE Sample END AS Sample
FROM t
To do the same automatically (i.e. to find the maximum of negatives and change it):
WITH MaxNeg AS (SELECT MAX(Sample) as v FROM t WHERE Sample < 0)
SELECT CASE WHEN Sample = MaxNeg.v THEN ABS(Sample) ELSE Sample END AS Sample
FROM t
If you want to change values in your row. You can use the following query.
update
t
set
sample = abs(sample)
where
sample = (select max(t.sample) from t where t.sample < 0)
But it you only need retrieve absolute value for maximum over negatives then use the following query. Really I think that clause where hasn't scary things and you can use it.
select abs(max(t.sample)) from t where t.sample < 0
Update
If you can use only select statement, then following decision can helps you.
with
t as
(
select 1281 as sample from dual union all
select -469 as sample from dual union all
select -469 as sample from dual union all
select -509 as sample from dual union all
select -1359 as sample from dual union all
select -1359 as sample from dual union all
select -2759 as sample from dual union all
select -2829 as sample from dual
)
select
case
when t.sample = (select max(t.sample) from t where t.sample < 0) then
abs(t.sample)
else
t.sample
end sample
from
t
And the result of this query is:
sample
-------
1281
469
469
-509
-1359
-1359
-2759
-2829
You can try the below SQL which filters all negative number. Then order by descending order of the negative numbers and select only the first row.
update tab
set tab.val = ABS(tab.val)
WHERE
tab.val < 0
ORDER BY tab.val DESC;
Hi i want to create a query which does the following. When the paramter 25 is selected it only runs part A of the query, if any other number is selected run both Table A and B select queries.
Example Below:
DECLARE #Type varchar (200)
select * from
(SELECT sort_code FROM dbo.Test 1
WHERE FUNDING_YEAR = 26)
union
(SELECT sort_code FROM dbo.Test 2
WHERE FUNDING_YEAR = 26)
Where case when #Type = 25 then select * from table2 else table 1
You just need to reference the variable in the WHERE clause
SELECT *
FROM TableA
WHERE #Type = 25
UNION
SELECT *
FROM TableB
The query above will always select everything in TableB and will only select everything in TableA when the variable is equal to 25.
Since you are using SSRS, what I would do is write the query to return all of the rows and then apply a filter in the SSRS report when the Paramater is 25. I wouldn't pass a paramater value to the SQL side unless it greatly reduces the run time of the query.
(I would have put this in a comment.)
Got a tricky one today (Might even just be me):
I have 8 Linked SQL 2012 servers configured to my main SQL server and I need to create table views so that I can filter all these combined table results only using one where clause, currently I use UNION because they all have the same table structures.
Currently my solution looks as follows:
SELECT * FROM [LinkedServer_1].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_2].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_3].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_4].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_5].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_6].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_7].[dbo].[Table] where value = 'xxx'
UNION
SELECT * FROM [LinkedServer_8].[dbo].[Table] where value = 'xxx'
As you can see this is becoming quite ugly because I have a select statement and where clause for each linked server and would like to know if there was a simpler way of doing this!
Appreciate the feedback.
Brakkie101
Instead of using views, you can use inline table-valued functions (a view with parameters). It will not save initial efforts for creating the queries, but could save some work in the future:
CREATE FUNCTION [dbo].[fn_LinkedSever] (#value NVARCHAR(128))
AS
RETURNS TABLE
AS
RETURN
(
SELECT * FROM [LinkedServer_1].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_2].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_3].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_4].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_5].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_6].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_7].[dbo].[Table] where value = #value
UNION
SELECT * FROM [LinkedServer_8].[dbo].[Table] where value = #value
);
Also, if possible, use UNION ALL instead of UNION.
I'm currently trying to do an SQL query that can detect if a SELECT query returns nothing, and then do another one if that is the case.
Here is what I mean:
IF SELECT * FROM table WHERE criteria = criteria RETURNS NO ROWS
THEN SELECT * FROM table WHERE criteria2 = criteria2
Is this possible? I don't think that an empty reply counts as "null" so I have a bit of a trouble with that.
You can do this in one statement, assuming the columns are the same:
SELECT *
FROM table
WHERE criteria = criteria
UNION ALL
SELECT *
FROM table
WHERE criteria2 = criteria2 AND
NOT EXISTS (SELECT 1 FROM table WHERE criteria = criteria);
You can use NOT EXISTS:
SELECT * FROM table WHERE criteria2 = criteria2
and not exists (
SELECT * FROM table WHERE criteria = criteria
)
union all
SELECT * FROM table WHERE criteria = criteria;
Here NOT EXISTS ensures that either part of the UNION ALL is returned. If the second criteria = criteria passes, then NOT EXISTS will return false and hence, only second part of the above query returns result. If it doesn't, it means, there are no rows with criteria = criteria and NOT EXISTS will return true and hence, only the first part return data.
I Did it like this
WITH
First AS (
SELECT t1.<field1>
FROM <schema1>.<table1> t1
WHERE
<criteria1>
[Other SQL Queries Options]
OFFSET 0
LIMIT 1
),
Second AS (
SELECT t2.<field2>
FROM <schema2>.<table2> t2
WHERE
<criteria2>
[Other SQL Queries Options]
OFFSET 0
LIMIT 1
)
SELECT <field1>
FROM First
UNION ALL
SELECT <field2> as <same name as field1>
FROM Second
WHERE NOT exists(
SELECT 1 FROM First
)
;
I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END