TSQL Conditional Select Statement - sql-server

Is it possible to write a SQL query that does the following:
Select * From Table1
if there are results, return them. Otherwise, use an alternative query and return it's results:
Select * From Table2
I came ups with the following, but it does not seem to work:
IF EXISTS(select * From TableA)
begin
Select * from TableA
end
else
Select * from TableB
Is there a simple elegant way of accomplishing this?

You can do a UNION query with NOT EXISTS:
SELECT * FROM TABLE1
UNION ALL
SELECT * FROM TABLE2 WHERE NOT EXISTS (SELECT * FROM TABLE1)
*Assuming the columns and types are the same

If both tables have same number of columns and the column names are same then you use Union, like below.
Select * from TableA
Union
Select * from TableB
If they have different column names or different number of columns then you can use below code.
Select Col_1 as col1, col_2 as col2.... From TableA
Union
Select col_a as Col1, col_b as Col2..... From TableB

Related

SQL Server append table to an existing table

I need to append rows from one table to an existing table. I am thinking something like following but this gives an error
select *
into table1
from (select *
from table1
union
select *
from table2) as tmp
Is there a way to use ALTER TABLE or UPDATE with UNION?
i will assume the below scenario ,
1- you need to insert in table1 all data from table 2
use this one
INSERT INTO TABLE1 (Col1, Col2)
SELECT Col1, COl2 FROM Table2
2- you have 2 tables , table 1 and need to insert in table 3
INSERT INTO TABLE3 (Col1, Col2)
SELECT Col1, COl2 FROM Table1
Union all --to remove duplication in data
SELECT Col1, COl2 FROM Table2
Just do a direct insert to Table1 from Table2
INSERT INTO TABLE1 (Col1, Col2)
SELECT
Col1, COl2
FROM
Table2
Use this query:
-- merge table1 and table2 data in temp table
SELECT * INTO #Temp
FROM
(
SELECT *
FROM table1
UNION
SELECT *
FROM table2
)
-- empty table1 and delete existing data
TRUNCATE TABLE table1
-- insert all merged data in table 1
INSERT INTO table1
SELECT *
FROM #Temp
You can remove duplicate rows with using UNION ALL instead of UNION

SQL IN clause multiple columns and multiple value

This query is fine works.
SELECT * FROM TABLE WHERE 330110042 IN (iItem01,iItem02,iItem03,iItem04,iItem05,iItem_1,iItem_2,iItem_3,iItem_4,iItem_5,iItem_6,iItem_7,iItem_8,iItem_9,iItem_10,iItem_11,iItem_12,iItem_13,iItem_14,iItem_15,iItem_16,iItem_17,iItem_18,iItem_19,iItem_20,iItem_21,iItem_22,iItem_23,iItem_24,iItem_25,iItem_26,iItem_27,iItem_28,iItem_29,iItem_30)
But this query didnt work.
SELECT * FROM TABLE WHERE 330110042, 330110002, 330110002 IN (iItem01,iItem02,iItem03,iItem04,iItem05,iItem_1,iItem_2,iItem_3,iItem_4,iItem_5,iItem_6,iItem_7,iItem_8,iItem_9,iItem_10,iItem_11,iItem_12,iItem_13,iItem_14,iItem_15,iItem_16,iItem_17,iItem_18,iItem_19,iItem_20,iItem_21,iItem_22,iItem_23,iItem_24,iItem_25,iItem_26,iItem_27,iItem_28,iItem_29,iItem_30)
How i work in SQL Server?
It's difficult to tell your exact goal here, but one possibility would be to turn the list of values into a table structure of its own. A Common Table Expression might work:
;WITH Ids AS
(
SELECT 330110042 AS Id
UNION ALL
SELECT 330110002
)
SELECT t.*
FROM [Table] t
INNER JOIN Ids i ON t.iItem01 = i.Id OR t.iItem02 = i.Id OR...
But, maybe a solution with UNPIVOT would be more elegant. I presume that your table has a primary key column called Id:
;WITH Unpivoted AS
(
SELECT Id, ColName, ColValue
FROM (SELECT Id, iItem01, iItem02, iItem03
FROM [Table] t) p
UNPIVOT
(ColValue FOR ColName IN (iItem01, iItem02, iItem03)) AS unpvt
)
SELECT t.*
FROM [Table] t
WHERE EXISTS (SELECT 1 FROM Unpivoted u
WHERE t.Id = u.Id
AND u.ColValue IN (330110042, 330110002))
Of course, you would add all the necessary columns. I added only the first three for this example.

Write alternative query in MSSQL view

I need to write a view which selects records from table1 if table1 does not contain so it goes to next alternative table like table2 or table3 etc.
Pl advice.
If what you need is to find the first match and return the results...then a view is not going to help you here. You need a stored procedure instead...something like...
create procedure spname
as
begin
if exists (select * from table1 [where clause condition])
select * from table1
else if exists (select * from table2 [where clause condition])
select * from table2
else if exists (select * from table3 [where clause condition])
select * from table3
end

Combine multiple results in a subquery into a single comma-separated value

I've got two tables:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
The relationship is one row of TableA - many of TableB.
Now, I want to see a result like this:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
This won't work (multiple results in a subquery):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
This is a trivial problem if I do the processing on the client side. But this will mean I will have to run X queries on every page, where X is the number of results of TableA.
Note that I can't simply do a GROUP BY or something similar, as it will return multiple results for rows of TableA.
I'm not sure if a UDF, utilizing COALESCE or something similar might work?
Even this will serve the purpose
Sample data
declare #t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into #t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
Query:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM #T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM #T T1
GROUP BY id,Name
Output:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
1. Create the UDF:
CREATE FUNCTION CombineValues
(
#FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #SomeColumnList VARCHAR(8000);
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = #FK_ID;
RETURN
(
SELECT #SomeColumnList
)
END
2. Use in subquery:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. If you are using stored procedure you can do like this:
CREATE PROCEDURE GetCombinedValues
#FK_ID int
As
BEGIN
DECLARE #SomeColumnList VARCHAR(800)
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB
WHERE FK_ID = #FK_ID
Select *, #SomeColumnList as SelectedIds
FROM
TableA
WHERE
FK_ID = #FK_ID
END
In MySQL there is a group_concat function that will return what you're asking for.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
I think you are on the right track with COALESCE. See here for an example of building a comma-delimited string:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
You may need to provide some more details for a more precise response.
Since your dataset seems kind of narrow, you might consider just using a row per result and performing the post-processing at the client.
So if you are really looking to make the server do the work return a result set like
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
which of course is a simple INNER JOIN on ID
Once you have the resultset back at the client, maintain a variable called CurrentName and use that as a trigger when to stop collecting SomeColumn into the useful thing you want it to do.
Assuming you only have WHERE clauses on table A create a stored procedure thus:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Then fill a DataSet ds with it. Then
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Finally you can add a repeater in the page that puts the commas for every line
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
In this way you will do it client side but with only one query, passing minimal data between database and frontend
I tried the solution priyanka.sarkar mentioned and the didn't quite get it working as the OP asked. Here's the solution I ended up with:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM #T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM #T T1
GROUP BY ID
Solution below:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
Use this, you also can change the Joins
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
This will work for selecting from different table using sub query.
I have reviewed all the answers. I think in database insertion should be like:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
The comma should be at previous end and do searching by like %,X,%

How to reduce 10+ union select statements

I need to extract a single column of data from 10+ columns of a single table. Instead of stacking up 10+ union select statements, is there another way of doing this without repeating the union select statements for each column?
I can get it by stacking up 10+ select statements like below:
select 'column_5' from table_a
union
select 'column_6' from table_a
union
select 'column_7' from table_a
union
.
.
.
union
select 'column_18' from table_a
Thanks for your time in advance :)
Using Cross Apply or UnPivot you can avoid multiple UNION statements
select Distinct COL
from table
Cross apply
(
values
(column_1),
(column_2),
..
..
(column_18)
)
CS (COL)
Note : Since you have used UNION i have kept Distinct in select. If you don't want to remove duplicates then remove Distinct from select
A query with UNPIVOT would look something like this....
SELECT *
FROM TableName t
UNPIVOT (Vals FOR N IN (Column1, Column2, Column3,....,Column10))up
Important note all the columns in IN clause must be of the same data type, if they are not use a sub-query to convert them to a uniform data type and then unpivot them something like...
SELECT *
FROM (
SELECT CAST(Column1 AS VARCHAR(200)) AS Column1
,CAST(Column2 AS VARCHAR(200)) AS Column2
,CAST(Column3 AS VARCHAR(200)) AS Column3
,.....
,CAST(Column10 AS VARCHAR(200)) AS Column10
FROM TableName) t
UNPIVOT (Vals FOR N IN (Column1, Column2, Column3,....,Column10))up

Resources