Execute query as per condition using case statement in joining - sql

I am using SQL SERVER 2008. My query is giving me errors. I want to fetch data OR execute a query from the table [DL_TRN]. If the record is not present in that table then I want to fetch details from another table [D_Loan]. I used the query :
DECLARE #DCount INTEGER;
SET #FCount=(SELECT COUNT(*) FROM [MsumCOOP].[dbo].[DL_TRN] WHERE [M_CODE]=6162 AND ([LOAN_COMP]<>'Y' OR [LOAN_COMP] IS NULL));
SELECT m.[CODE],m.[NAME],d.[OP_AMT]
FROM [MsumCOOP].[dbo].[MEMBER] m
FULL OUTER JOIN ( SELECT CASE WHEN #FCount>0 THEN (SELECT [M_CODE],[OP_AMT] FROM [MsumCOOP].[dbo].[DL_TRN] WHERE [LOAN_COMP]<>'Y' )
ELSE (SELECT [M_CODE],'F' AS [OP_AMT] FROM [MsumCOOP].[dbo].[D_Loan] WHERE [LOAN_COMP]<>'Y')
END
)
d ON m.[CODE]=d.[M_CODE]
WHERE m.code=6162
Above query works fine if I just select a single field Like [M_CODE] or count (in subquery in joining part) but not working for selecting multiple columns.
Please guide me to do this query.

You can't put a subquery that returns more than one column in the THEN clause of a CASE expression.
I know it's more code, but your code will actually perform faster if you write it like this:
IF #FCount>0
SELECT ... {query that joins to DL_TRN}
ELSE
SELECT ... {query that joins to D_LOAN}
END

Related

Why do these two "not in" queries have different results?

We are trying to weed out records that have a duplicate of certain columns. I built this query to show any row that has an 'N' for its Flag, if there is not a matching 'Y' record in the table with the same last/first name.
select * from Table where LName+FName not in
(select LName+FName from Table where FLAG = 'y')
However this comes back with 0 results. The inner query does return expected results. If I run the inner query, and manually paste in the result values like below, it runs with results.
select * from Table where LName+Fname not in ('DoeJohn','AbelAdam')
What exactly is going on here?
I would suggest looking at your data... NOT IN fails when there is any NULL value. You can try either using NOT EXISTS or filtering any null values:
select * from Table where LName+FName not in
(select LName+FName from Table where FLAG = 'y' AND LName+FName IS NOT NULL)

Ibatis SQL query

I have the below query :
Select top 20 * from tab
--(first query)
union all
Select '0' as id,'PR' as BU,tab.name,tab.desc from tablename tab
inner join tablename1 tab1 ON tab1.name=tab.name and tab1.desc=tab.desc
--(second query)
union all
Select '0' as id,'BR' as BU,tab.name,tab.desc from tablename tab
inner join tablename1 tab1 ON tab1.name=tab.name and tab1.desc=tab.desc
--(third query)
Here i am trying to put the filter in the above query if i pass 'PR' as BU it should give me results of query 1 and query 2 but right now it is giving me results of all the three queries.
I need the results on basis of parameter of BU
There are no parameters in your SQL but this is something that ibatis can help you with. By using dynamic SQL you can have ibatis generate multiple prepared statements and using the correct one at runtime based on input.

Subquery returns more than one row and stops working

I have a table which has got a column. I have to fetch the values from the column and modify it in the view before comparing it with an externally supplied value.
For that I am using the following query:
SELECT COUNT(*)
FROM tblMaster WITH (NOLOCK)
WHERE (SELECT test
FROM
(SELECT RIGHT('00000000000000000' + RTRIM(CODE), 17) as test
FROM tblMaster ) t) = '00001231231231231'
Subquery returns modified values of the column extracted from the actual table in form of a column. So I am using the column returned out of the subquery. I don't know if I can use a subquery which returns a column on the left side of equality.
Subquery returns multiple values.
You don't need a subquery for this:
SELECT COUNT(*)
FROM tblMaster WITH (NOLOCK)
WHERE right('00000000000000000' + RTRIM(CODE), 17) = '00001231231231231';
You can simplify this. You don't need to add 0s to integers, SQL will trim them off when comparing. Also you don't need the subquery:
SELECT COUNT(*)
FROM tblMaster WITH (NOLOCK)
WHERE CODE = '1231231231231'

SELECT-CASE-IN-SELECT error: [SQL0115] Comparison operator IN not valid. In query db2

i have a problem in a db2 query
I tried run this query
SELECT t.* ,
CASE WHEN column in (SELECT data FROM otherTable WHERE conditions...)
then 5
else 0
end as 'My new data'
FROM table t
WHERE conditions....
But get error
[Error Code: -115, SQL State: 42601] [SQL0115] Comparison operator IN not valid.
When i change the sub-query to where statement like this
SELECT t.*
FROM table t
WHERE column in (SELECT data FROM otherTable WHERE conditions...)
Works fine
Why not work in the case statement? It is a limitation of db2?
And could make an equivalent behavior?
One way to do this is to left join to the table and check if it is not null.
In most cases this will be the fastest way because SQL servers are optimized to perform joins very quickly (but will depend on a number of factors including data model, indexes, data size, etc).
Like this:
SELECT t.* ,
CASE WHEN othertable.data is not null
then 5
else 0
end as 'My new data'
FROM table t
left join otherTable ON otherTable.column = data
WHERE conditions....
Try with using exists condition as below (put the column value in the where clause of subquery) :
SELECT t.* ,
CASE WHEN exists (SELECT data FROM otherTable WHERE conditions... and column=val)
then 5
else 0
end as 'My new data'
FROM table t
WHERE conditions....

sql select into subquery

I'm doing a data conversion between systems and have prepared a select statement that identifies the necessary rows to pull from table1 and joins to table2 to display a pair of supporting columns. This select statement also places blank columns into the result in order to format the result for the upload to the destination system.
Beyond this query, I will also need to update some column values which I'd like to do in a separate statement operation in a new table. Therefore, I'm interested in running the above select statement as a subquery inside a SELECT INTO that will essentially plop the results into a staging table.
SELECT
dbo_tblPatCountryApplication.AppId, '',
dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus, ...
FROM
dbo_tblPatInvention
INNER JOIN
dbo_tblPatCountryApplication ON dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId
ORDER BY
dbo_tblpatcountryapplication.invid;
I'd like to execute the above statement so that the results are dumped into a new table. Can anyone please advise how to embed the statement into a subquery that will play nicely with a SELECT INTO?
You can simply add an INTO clause to your existing query to create a new table filled with the results of the query:
SELECT ...
INTO MyNewStagingTable -- Creates a new table with the results of this query
FROM MyOtherTable
JOIN ...
However, you will have to make sure each column has a name, as in:
SELECT dbo_tblPatCountryApplication.AppId, -- Cool, already has a name
'' AS Column2, -- Given a name to create that new table with select...into
...
INTO MyNewStagingTable
FROM dbo_tblPatInvention INNER JOIN ...
Also, you might like to use aliases for your tables, too, to make code a little more readable;
SELECT a.AppId,
'' AS Column2,
...
INTO MyNewStagingTable
FROM dbo_tblPatInvention AS i
INNER JOIN dbo_tblPatCountryApplication AS a ON i.InvId = a.InvId
ORDER BY a.InvId
One last note is that it looks odd to have named your tables dbo_tblXXX as dbo is normally the schema name and is separated from the table name with dot notation, e.g. dbo.tblXXX. I'm assuming that you already have a fully working select query before adding the into clause. Some also consider using Hungarian notation in your database (tblName) to be a type of anti-pattern to avoid.
If the staging table doesn't exist and you want to create it on insert then try the following:
SELECT dbo_tblPatCountryApplication.AppId,'', dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus .......
INTO StagingTable
FROM dbo_tblPatInvention
INNER JOIN dbo_tblPatCountryApplication
ON dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId;
If you want to insert them in a specific order then use try using a sub-query in the from clause:
SELECT *
INTO StagingTable
FROM
(
SELECT dbo_tblPatCountryApplication.AppId, '', dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus .......
FROM dbo_tblPatInvention
INNER JOIN dbo_tblPatCountryApplication ON
dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId
order by dbo_tblpatcountryapplication.invid
) a;
Try
INSERT INTO stagingtable (AppId, ...)
SELECT ... --your select goes here