choosing between two tables in SQL Server - sql-server

Question for you - not sure if it is feasible however.
I have a scenario where I want to SELECT a set of data from one table if it exists there then if it doesn't I want to SELECT it from a different table where I know it will exist. The issue is they have slightly different field names in some cases. I am curious if a CASE clause would be the best way to do this?
i.e.:
SELECT example1,
example1a
FROM database 1 (if it exists)
if not SELECT from database 2 (where it will exist)

If this is column by column basis you can use this most likely.
SELECT
coalesce(db1.example1,db2.example1),
coalesce(db1.example1a, db2.example1a)
FROM
database1 db1
FULL OUTER JOIN
database2 db2 on
db1.id = db2.id
If you are wanting to choose one or the other, you can use exists()
if exists(select 1 from VW_ARUN_NORM_NEW WHERE REQ_CAT LIKE '%1000%' R REQ_CAT LIKE '%2000%')
begin
SELECT TOP
MATERIAL_NUMBER,
SALES_ORDER_NUMBER,
REQ_CAT,
PLANT,
REQUESTED_DELIV_DATE
FROM VW_ARUN_NORM_NEW
WHERE
REQ_CAT LIKE '%1000%'
OR REQ_CAT LIKE '%2000%'
end
else
begin
SELECT
MATERIAL,
SALES_ORDER_NUMBER,
REQUIREMENT_CATEGORY,
PLANT_CODE,
REQUESTED_DELIVERY_DATE
FROM
VW_MRP_ALLOCATION
WHERE
REQUIREMENT_CATEGORY LIKE '%5000%'
end

ISNULL() from an OUTER JOIN of the two tables is probably the best way.

you could use if exists clause example
IF EXISTS (select example1 from database1)
begin
--do something
end
else
begin
--do another query
end
or you can check if the table exists:
(select top 1 name from sys.tables where name = 'ACTIVSOC2')
but when you select the table of the query must exists.
Hope you help

Related

Is it possible to execute the same query i'm using inside an IF EXISTS statement without repeating it?

This really silly question just popped out of my mind out of curiosity; i'm still learning how to write better code in SQL and i just found myself in the situation where i have to check if the result of a query exists and then, if that was true, execute the same exact query to create a new table.
The code is working and considering i'm not dealing with large amounts of data i have no problems of computation times but...it's simply ugly and i would like to make it more...appealing?
This is the code i'm refering to:
[...]
IF EXISTS (SELECT *value*, COUNT(*) AS Repetitions
FROM *table*
GROUP BY *value*
HAVING COUNT(*) > 1)
SELECT *value*, COUNT(*) AS Repetitions
INTO dbo.*newtable*
FROM *table*
GROUP BY *data*
HAVING COUNT(*) > 1
ELSE
[...]
Doing an exists first is unecessary.
Simply do
select <columns> into NewTable
From Table
where criteria;
if ##rowcount=0
begin
drop table NewTable;
end
else
begin
/* Actions if table created */
end

Need help on SQL Server 2008 programming

I am very new to SQL Server 2008 programming and trying to create a procedure.
Well, the requirement is 'The procedure returns data either based on the input parameter OR if no input data is given-it should do a default select and return all data qualifying'
I tried out with something like this-
CREATE PROCEDURE [dbo].[Proc_sampletestproc]
(#testid int)
AS
BEGIN
SET NOCOUNT OFF; ----I worked with Oracle PL/SQL and so do we need for mandatory this declarations
Here, I need to put a check that if the input testid has a value or not. If it exists, we have one case with a select or we do a default select.
Also, I am putting a direct SELECT with no joins on tables. How would I JOIN the tables along with OUTER JOINS because a testid may or may not have an insurance? I mean syntactically - syntax is quite different in SQL Server.
SELECT
T.TESTID, T.NAME, TI.INSURENAME
FROM
testinsured ti, test t, testinsuredHistory tih
WHERE
t.testid = ti.testid -----This entry may be there or not IN THE testinsured TABLE
AND tih.testinsuredid = ti.testinsuredid --A testid might have 2 Insurers whose history is stored here.
AND TIH.STARTDATE IS NOT NULL
AND TIH.ENDDATE IS NOT NULL --TO CHECK ACTIVE DATES FOR COVERAGE
Also, I want to do a group by on testid so that the name comes once but the InsuredPlanname comes accordingly once, twice as many as each Testid has.
if (#testid is not null)
begin
/* ... */
end
else
begin
SELECT T.TESTID,T.NAME,TI.INSURENAME
FROM test t
left outer join testinsured ti on t.testid = ti.testid -----This entry may be there or not IN THE testinsured TABLE
left outer join testinsuredHistory tih on ti.testinsuredid = tih.testinsuredid --A testid might have 2 Insurers whose history is stored here.
where TIH.STARTDATE IS NOT null AND TIH.ENDDATE IS NOT NULL
/* group by ... */
end

Use a locking hint or top clause for a view which only selects newid()?

In order to use newid() in a UDF, I've created a view that can help me:
create view RandomUUID as select newid() as UUID
In this way, UDFs can now get access to newid(). Cool.
My question, however, is what is the best way to select this? Does it make sense to add a TOP 1 or (nolock) to the query in my UDF? As in:
select UUID from RandomUUID
vs.
select top 1 UUID from RandomUUID (nolock) -- Or any other combo of query modifiers
UPDATE:
This SqlFiddle demonstrates how this is being used.
There is no reason to add (nolock) because there is no record involved to lock! For the record, (NOLOCK) should be written as WITH (nolock) from SQL Server 2008 onwards (or was it 2005).
TOP (1) will add a SORT operator here that will be extraneous, since there is only ever one row created.
You can create it like this:
create view RandomUUID as select newid() as UUID;
GO
create function give_me_a_new_id ()
returns uniqueidentifier as
begin
return (select UUID from RandomUUID);
end;
GO
Note: (nolock) will be optimized away, but TOP(1) adds a SORT operation as seen here (expand the Execution plans).

compare file names from one query against another query sql

I have a situation where I am suppose to compare a document name from one query against query.
I have a table called tbl_doc which consists document_name column.
Another table called tbl_content which consists content_name.
And I have two select queries like
select document_name from tbl_doc
select content_name from tbl_content.
SO I need to compare document_name against content_name if they are equal then need to do a insert operation.
Thanks
You probably mean to check if a certain value exists...
IF EXISTS(
SELECT 1 FROM [tbl_doc]
JOIN [tbl_content] ON [tbl_doc].[document_name] = [tbl_content].[content_name]
WHERE [tbl_doc].[document_name] = #Name )
BEGIN
INSERT INTO [...]
(
...
)
SELECT
...
END
select document_name,content_name
from tbl_doc
join tbl_content on document_name=content_name

Is there a way to optimize the query given below

I have the following Query and i need the query to fetch data from SomeTable based on the filter criteria present in the Someothertable. If there is nothing present in SomeOtherTable Query should return me all the data present in SomeTable
SQL SERVER 2005
SomeOtherTable does not have any indexes or any constraint all fields are char(50)
The Following Query work fine for my requirements but it causes performance problems when i have lots of parameters.
Due to some requirement of Client, We have to keep all the Where clause data in SomeOtherTable. depending on subid data will be joined with one of the columns in SomeTable.
For example the Query can can be
SELECT
*
FROM
SomeTable
WHERE
1=1
AND
(
SomeTable.ID in (SELECT DISTINCT ID FROM SomeOtherTable WHERE Name = 'ABC' and subid = 'EF')
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'EF')
)
AND
(
SomeTable.date =(SELECT date FROM SomeOtherTable WHERE Name = 'ABC' and subid = 'Date')
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'Date')
)
EDIT----------------------------------------------
I think i might have to explain my problem in detail:
We have developed an ASP.net application that is used to invoke parametrize crystal reports, parameters to the crystal reports are not passed using the default crystal reports method.
In ASP.net application we have created wizards which are used to pass the parameters to the Reports, These parameters are not directly consumed by the crystal report but are consumed by the Query embedded inside the crystal report or the Stored procedure used in the Crystal report.
This is achieved using a table (SomeOtherTable) which holds parameter data as long as report is running after which the data is deleted, as such we can assume that SomeOtherTable has max 2 to 3 rows at any given point of time.
So if we look at the above query initial part of the Query can be assumed as the Report Query and the where clause is used to get the user input from the SomeOtherTable table.
So i don't think it will be useful to create indexes etc (May be i am wrong).
SomeOtherTable does not have any
indexes or any constraint all fields
are char(50)
Well, there's your problem. There's nothing you can do to a query like this which will improve its performance if you create it like this.
You need a proper primary or other candidate key designated on all of your tables. That is to say, you need at least ONE unique index on the table. You can do this by designating one or more fields as the PK, or you can add a UNIQUE constraint or index.
You need to define your fields properly. Does the field store integers? Well then, an INT field may just be a better bet than a CHAR(50).
You can't "optimize" a query that is based on an unsound schema.
Try:
SELECT
*
FROM
SomeTable
LEFT JOIN SomeOtherTable ON SomeTable.ID=SomeOtherTable.ID AND Name = 'ABC'
WHERE
1=1
AND
(
SomeOtherTable.ID IS NOT NULL
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC')
)
also put 'with (nolock)' after each table name to improve performance
The following might speed you up
SELECT *
FROM SomeTable
WHERE
SomeTable.ID in
(SELECT DISTINCT ID FROM SomeOtherTable Where Name = 'ABC')
UNION
SELECT *
FROM SomeTable
Where
NOT EXISTS (Select spName From SomeOtherTable Where spName = 'ABC')
The UNION will effectivly split this into two simpler queries which can be optiomised separately (depends very much on DBMS, table size etc whether this will actually improve performance -- but its always worth a try).
The "EXISTS" key word is more efficient than the "SELECT COUNT(1)" as it will return true as soon as the first row is encountered.
Or check if the value exists in db first
And you can remove the distinct keyword in your query, it is useless here.
if EXISTS (Select spName From SomeOtherTable Where spName = 'ABC')
begin
SELECT *
FROM SomeTable
WHERE
SomeTable.ID in
(SELECT ID FROM SomeOtherTable Where Name = 'ABC')
end
else
begin
SELECT *
FROM SomeTable
end
Aloha
Try
select t.* from SomeTable t
left outer join SomeOtherTable o
on t.id = o.id
where (not exists (select id from SomeOtherTable where spname = 'adbc')
OR spname = 'adbc')
-Edoode
change all your select statements in the where part to inner jons.
the OR conditions should be union all-ed.
also make sure your indexing is ok.
sometimes it pays to have an intermediate table for temp results to which you can join to.
It seems to me that there is no need for the "1=1 AND" in your query. 1=1 will always evaluate to be true, leaving the software to evaluate the next part... why not just skip the 1=1 and evaluate the juicy part?
I am going to stick to my original Query.

Resources