Related
This is the Scenario : I have a duplicate rows in my table with the same Id , Name and so on .
1) I have to find the duplicate row matching all the criteria ( this is done)
2) Delete them only if the criteria match
3) Use the id of the deleted record and update the existing row in the table
For this i have created a 2 temp table. Temp1 is the table with all the record. Temp2 consist of duplicated row.
IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
DROP TABLE #Temp1
IF OBJECT_ID('tempdb..#Temp2') IS NOT NULL
DROP TABLE #Temp2
IF OBJECT_ID('tempdb..#Temp3') IS NOT NULL
DROP TABLE #Temp3
CREATE Table #Temp1 (
Id int,
Name NVARCHAR(64),
StudentNo INT NULL,
ClassCode NVARCHAR(8) NULL,
Section NVARCHAR(8) NULL,
)
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(1,'Joe',123,'A1', 'I')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(1,'Joe',123,'A1', 'I')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(2,'Harry',113,'X2', 'H')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(2,'Harry',113,'X2', 'H')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(3,'Elle',121,'J1', 'E1')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(3,'Elle',121,'J1', 'E')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(8,'Jane',191,'A1', 'E')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(5,'Silva',811,'S1', 'SE')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(6,'Juan',411,'S2', 'SE')
INSERT INTO #Temp1 (Id, Name,StudentNo,ClassCode,Section) Values(7,'Carla',431,'S2', 'SE')
;WITH CTE AS (
select
ROW_NUMBER() over (partition by Id
, StudentNo
order by Id, StudentNo)as Duplicate_RowNumber
, * from #Temp1 )
select t1.Id,t1.Name,t1.StudentNo,t1.Section,t1.ClassCode
INTO #Temp2
from CTE as c INNER JOIN #Temp1 as t1 ON t1.Id = c.Id
and t1.StudentNo = t1.StudentNo
and c.Duplicate_RowNumber >1
-- this will have 6 rows all the duplicates are included
--select * from #Temp2
-- this is for output clause
DECLARE #inserted Table (Id int,
Name NVARCHAR(64),
StudentNo INT NULL,
ClassCode NVARCHAR(8) NULL,
Section NVARCHAR(8) NULL)
DELETE FROM #temp1
OUTPUT deleted.Id , deleted.Name ,deleted.StudentNo ,deleted.ClassCode ,deleted.Section into #inserted
WHERE EXISTS ( SELECT * FROM #Temp2 as t2
where #temp1.Id = t2.Id
and #temp1.Name = t2.Name
and #temp1.StudentNo = t2.StudentNo
and #temp1.ClassCode = t2.ClassCode
and #temp1.Section = t2.Section)
-- this is to check what is delete so that i can join it and update the table temp1
select * from #inserted
You can see below the query should not delete the last two highlighted column because the Section does not match. It should only delete matching criteria from Temp1 and Temp2.
Scenario 2 : Delete the duplicate record in Temp1 and use the key in order to update the data to NULL for Section and Classcode . This is what i expect with the highlighted to be NULLs .
You can run this query yourself - just copy and paste.
Yes, for scenario #1 it is going to delete the rows because the problem is in this section.
I added this table for references.
Added this #temp2 table to clarify for later use.
CREATE Table #Temp2 (
Id int,
Name Varchar(64),
StudentNo INT NULL,
ClassCode Varchar(8) NULL,
Section Varchar(8) NULL,
)
IF OBJECT_ID('tempdb..#tmp4') IS NOT NULL
DROP TABLE #tmp4
select t1.Id,t1.Name,t1.StudentNo,t1.Section,t1.ClassCode,
Duplicate_RowNumber
INTO #Duplicatedata
from CTE as c INNER JOIN #Temp1 as t1 ON t1.Id = c.Id
and t1.StudentNo = t1.StudentNo
and c.Duplicate_RowNumber >1
select * from #Duplicatedata
This is going to satisfy both condition as #temp 1 will have both rows for Elle as your join condition is only on ID and Student No.
I added row number column for clarity.
Id Name StudentNo Section ClassCode Duplicate_RowNumber
1 Joe 123 I A1 2
1 Joe 123 I A1 2
2 Harry 113 H X2 2
2 Harry 113 H X2 2
3 Elle 121 E1 J1 2
3 Elle 121 E J1 2
As your Partition is based by Student No and ID, every duplicate row will have 2 or more row numbers.
You can use this approach to delete.
select
ROW_NUMBER() over (partition by Id
, StudentNo
order by Id, StudentNo, section)as Duplicate_RowNumber
, * into #tmp4 from #Temp1
--You can add section in your order as well for consistency purpose.
delete
from #tmp4
output deleted.id, deleted.Name, deleted.StudentNo, deleted.ClassCode,
deleted.Section into #Temp2
where Duplicate_RowNumber > 1
After that it seems like you want to keep one row in your final table and put the other one in you deleted table. For Elle it will delete one of the rows from Final table and keep only one since your partition is not based on section.
To make sure that you delete 1 row from your final table you can use this.
DELETE t
OUTPUT deleted.Id , deleted.Name ,deleted.StudentNo ,deleted.ClassCode
,deleted.Section into #inserted FROM
(select *, row_number() over (Partition by tm.name, tm.studentNo Order by ID,
StudentNo, section ) rownum from #temp1 tm) t
join #Temp2 t2 on t.Id = t2.Id
and t.Name = t2.Name
and t.StudentNo = t2.StudentNo
and t.ClassCode = t2.ClassCode
and t.Section = t2.Section
where t.rownum > 1
If you notice I added this row number, so that it will not two delete the rows from final table, since Joe and Harry has all the matching attributes, and it will delete two rows.
select * from #inserted
Output you get:
Id Name StudentNo ClassCode Section
3 Elle 121 J1 E1
2 Harry 113 X2 H
1 Joe 123 A1 I
Finally you can update final table in this way. #Scenario 2
update TMP
SET ClassCode = NULL, SECTION = NULL
FROM
#Temp1 TMP
JOIN #INSERTED I ON TMP.Id = I.Id
AND TMP.StudentNo = I.StudentNo
SELECT * FROM #Temp1
Final Output:
Id Name StudentNo ClassCode Section
1 Joe 123 NULL NULL
2 Harry 113 NULL NULL
3 Elle 121 NULL NULL
8 Jane 191 A1 E
5 Silva 811 S1 SE
6 Juan 411 S2 SE
7 Carla 431 S2 SE
Please note that I have added scripts and output only for the parts where it required change, and rest part is same script provided by you.
I am trying to get the SUM from two different but related tables that have a one to many relationship, but when I add a where condition to the second table the first does not properly sum up the total. Can this be done in a single query? I should also note that it is critical that both consider the same set of LocationId's as they come from an outside filter. I also need the Activityname condition to happen after the join if at all possible. If that isn't possible then that is fine.
IF OBJECT_ID('tempdb..#tmpVisits') is not null
begin
drop TABLE #tmpVisits
end
IF OBJECT_ID('tempdb..#tmpVisitsByActivity') is not null
begin
drop TABLE #tmpVisitsByActivity
end
CREATE TABLE #tmpVisits
(
AccountId int,
LocationId int,
Dt DATE,
TotalVisits int
)
CREATE TABLE #tmpVisitsByActivity
(
AccountId int,
LocationId int,
EventDate DATE,
TotalCompleted INT,
ActivityName varchar(20)
)
insert INTO #tmpVisits
SELECT 1,10,'2018-09-12',12
union ALL
SELECT 1,11,'2018-09-12',20
union ALL
SELECT 1,22,'2018-09-12',10
insert INTO #tmpVisitsByActivity
SELECT 1,10,'2018-09-12',55,'ActivityA'
union ALL
SELECT 1,10,'2018-09-12',1,'ActivityA'
union ALL
SELECT 1,10,'2018-09-12',2,'ActivityB'
union ALL
SELECT 1,22,'2018-09-12',3,'ActivityC'
SELECT SUM(v.TotalVisits) --expecting 42 actual 10
, SUM(a.TotalCompleted) --expecting 3 actual 3
FROM #tmpVisits v
left JOIN #tmpVisitsByActivity a
ON v.AccountId = a.AccountId
AND v.dt = a.EventDate
AND v.LocationId = a.locationid
WHERE v.dt='2018-09-12' AND v.AccountId=1
AND a.ActivityName='ActivityC'
You can move the where condition clauses in the join condition like below, if you want to use a single query.
SELECT SUM(v.TotalVisits) --expecting 42 actual 10
, SUM(a.TotalCompleted) --expecting 3 actual 3
FROM #tmpVisits v
left JOIN #tmpVisitsByActivity a
ON v.AccountId = a.AccountId
AND v.dt = a.EventDate
AND v.LocationId = a.locationid
AND v.dt='2018-09-12' AND v.AccountId=1
AND a.ActivityName='ActivityC'
The last criteria makes it so that some in #tmpVisits are excluded when there's no match.
But that's easy to get around.
Move the criteria for a.ActivityName to the ON clause, and remove it from the WHERE clause.
...
LEFT JOIN #tmpVisitsByActivity a
ON a.AccountId = v.AccountId AND
a.EventDate = v.dt AND
a.LocationId = v.locationId AND
a.ActivityName = 'ActivityA'
WHERE v.dt = '2018-09-12'
AND v.AccountId = 1
But it would be better to put the second table in a sub-query. Otherwise the first SUM could be wrong.
Example snippet:
DECLARE #Visits TABLE
(
AccountId INT,
LocationId INT,
Dt DATE,
TotalVisits INT
);
DECLARE #VisitsByActivity TABLE
(
AccountId INT,
LocationId INT,
EventDate DATE,
TotalCompleted INT,
ActivityName VARCHAR(20)
);
INSERT INTO #Visits (AccountId, LocationId, Dt, TotalVisits) VALUES
(1,10,'2018-09-12',12),
(1,11,'2018-09-12',20),
(1,22,'2018-09-12',10);
INSERT INTO #VisitsByActivity (AccountId, LocationId, EventDate, TotalCompleted, ActivityName) VALUES
(1,10,'2018-09-12',55,'ActivityA'),
(1,10,'2018-09-12',1,'ActivityA'),
(1,10,'2018-09-12',2,'ActivityB'),
(1,22,'2018-09-12',1,'ActivityC'),
(1,22,'2018-09-12',2,'ActivityC');
SELECT
SUM(v.TotalVisits) AS TotalVisits,
SUM(ac.TotalCompleted) AS TotalCompleted
FROM #Visits v
LEFT JOIN
(
SELECT AccountId, EventDate, locationid,
SUM(TotalCompleted) AS TotalCompleted
FROM #VisitsByActivity
WHERE ActivityName = 'ActivityC'
GROUP BY AccountId, EventDate, locationid
) AS ac
ON (ac.AccountId = v.AccountId AND ac.EventDate = v.dt AND ac.LocationId = v.locationid)
WHERE v.dt = '2018-09-12'
AND v.AccountId=1
I'm trying to create a view where the user sees one line per "Batch" joined so that when the "Batch" from the different tables match - then they should go together as one line. But if either table on itself has the "Batch" it should also be added to the result as a row with "NULL" in the other columns.
I think the problem is with how I join the tables. But I can't quite figure out the problem.
CREATE TABLE #ItemTable ([Item] nvarchar(16))
CREATE TABLE #LocationTable ([Item] nvarchar(16), [Batch] nvarchar(32), [Location] nvarchar(13), [Quantity] int)
CREATE TABLE #OrderTable ([Item] nvarchar(16), [Batch] nvarchar(32), [Quantity] int)
CREATE TABLE #BookingTable ([Item] nvarchar(16), [Batch] nvarchar(32), [Quantity] int)
--------------------------------------------------------------------------------------------------
-- CURRENT RESULT:
--------------------------------------------------------------------------------------------------
-- Item Batch Location QuantityOnLocation OrderedQuantity BookedQuantity
-- 1000 1 Location_1 10 NULL NULL
-- 1000 22 Location_2 10 NULL NULL
-- 2000 333 Location_3 0 10 NULL
-- 2000 4444 Location_4 10 NULL NULL
-- 3000 666666 NULL NULL 10 10
--------------------------------------------------------------------------------------------------
-- DESIRED RESULT:
--------------------------------------------------------------------------------------------------
-- Item Batch Location QuantityOnLocation OrderedQuantity BookedQuantity
-- 1000 1 Location_1 10 NULL 10
-- 1000 22 Location_2 10 NULL 0
-- 1000 55555 NULL NULL NULL 10
-- 2000 333 Location_3 0 10 NULL
-- 2000 4444 Location_4 10 NULL NULL
-- 3000 666666 NULL NULL 10 10
INSERT INTO #ItemTable ([Item]) VALUES
('1000'),
('2000'),
('3000')
INSERT INTO #LocationTable ([Item], [Batch], [Location], [Quantity]) VALUES
('1000', '1', 'Location_1', 10),
('1000', '22', 'Location_2', 10),
('2000', '333', 'Location_3', 0),
('2000', '4444', 'Location_4', 10)
INSERT INTO #OrderTable ([Item], [Batch], [Quantity]) VALUES
('2000', '333', 10),
('3000', '666666', 10)
INSERT INTO #BookingTable ([Item], [Batch], [Quantity]) VALUES
('1000', '1', 10),
('1000', '55555', 10),
('3000', '666666', 10)
SELECT
[Item].[Item] AS [Item],
COALESCE([Location].[Batch], [Order].[Batch], [Booking].[Batch]) AS [Batch],
[Location].[Location] AS [Location],
[Location].[Quantity] AS [QuantityOnLocation],
[Order].[Quantity] AS [OrderedQuantity],
[Booking].Quantity AS [BookedQuantity]
FROM
#ItemTable AS [Item]
LEFT OUTER JOIN (
SELECT [Item], [Quantity], [Batch], [Location]
FROM #LocationTable)
AS [Location] ON [Location].[Item] = [Item].[Item]
LEFT OUTER JOIN (
SELECT [Item], [Quantity], [Batch]
FROM #OrderTable)
AS [Order] ON [Order].[Item] = [Item].[Item]
AND ISNULL([Order].[Batch], '') = ISNULL([Location].[Batch], [Order].[Batch])
LEFT OUTER JOIN (
SELECT [Item], [Quantity], [Batch]
FROM #BookingTable)
AS [Booking] ON [Order].[Item] = [Item].[Item]
AND ISNULL([Booking].[Batch], '') = COALESCE([Location].[Batch], [Order].[Batch], [Booking].[Batch])
WHERE
ISNULL([Location].[Quantity], 0) <> 0
OR ISNULL([Order].[Quantity], 0) <> 0
OR ISNULL([Booking].Quantity, 0) <> 0
DROP TABLE #ItemTable
DROP TABLE #LocationTable
DROP TABLE #BookingTable
DROP TABLE #OrderTable
You made a typo (I think) on your last join, this bit:
LEFT OUTER JOIN (
SELECT [Item], [Quantity], [Batch]
FROM #BookingTable)
AS [Booking] ON [Order].[Item] = [Item].[Item]
Should that not be:
ON [Booking].[Item] = [Item].[Item]
I rewrote your query slightly to this:
SELECT
i.Item AS Item,
COALESCE(l.Batch, o.Batch, b.Batch) AS Batch,
l.Location AS Location,
l.Quantity AS QuantityOnLocation,
o.Quantity AS OrderedQuantity,
b.Quantity AS BookedQuantity
FROM
#ItemTable i
LEFT JOIN #LocationTable l ON l.Item = i.Item
LEFT JOIN #OrderTable o ON o.Item = i.Item AND o.Batch = ISNULL(l.Batch, o.Batch)
LEFT JOIN #BookingTable b ON b.Item = i.Item AND b.Batch = COALESCE(l.Batch, o.Batch, b.Batch)
WHERE
ISNULL(l.Quantity, 0) != 0
OR ISNULL(o.Quantity, 0) != 0
OR ISNULL(b.Quantity, 0) != 0;
Which seems more readable to me, but I guess this is personal preference?
Then I realised that this still doesn't give you what you want, so I refactored it again to get this (which does give you the desired results):
WITH UniqueItemBatch AS (
SELECT DISTINCT Item, Batch FROM #LocationTable
UNION
SELECT DISTINCT Item, Batch FROM #OrderTable
UNION
SELECT DISTINCT Item, Batch FROM #BookingTable)
SELECT
u.Item AS Item,
u.Batch,
l.Location AS Location,
l.Quantity AS QuantityOnLocation,
o.Quantity AS OrderedQuantity,
b.Quantity AS BookedQuantity
FROM
UniqueItemBatch u
LEFT JOIN #ItemTable i ON i.Item = u.Item
LEFT JOIN #LocationTable l ON l.Item = u.Item AND l.Batch = u.Batch
LEFT JOIN #OrderTable o ON o.Item = u.Item AND o.Batch = u.Batch
LEFT JOIN #BookingTable b ON b.Item = u.Item AND b.Batch = u.Batch
WHERE
ISNULL(l.Quantity, 0) != 0
OR ISNULL(o.Quantity, 0) != 0
OR ISNULL(b.Quantity, 0) != 0;
I'm not sure as to the logic for your final column, but this gives the desired results for the other columns.
To get your query based on either bookings or locations showing as a batch, I have unioned the two tables together in the query.
I would suggest, if possible, revisiting the design of your data structure
select
item.Item,
batch.Batch,
max(batch.location) as location,
sum(batch.LQuantity) as QuantityOnLocation,
orders.Quantity as OrderedQuantity,
sum(batch.BQuantity) as BookedQuantity
from
#ItemTable item
left join
(
select Item, Batch, quantity as BQuantity, null as Location, null as LQuantity from #BookingTable
union
select item, Batch, null, Location, Quantity as LQuantity from #LocationTable
) batch
on item.Item = batch.Item
left join #OrderTable orders
on item.Item = orders.Item and batch.Batch = orders.Batch
group by
item.Item,
batch.Batch,
orders.Quantity
I think I would prefer a different approach. How about you take all the batchnumbers and add all the columns as empty columns. Then you update the different columns form each table.
Like this:
SELECT INTO #MyTableResult Batch FROM TableA
UNION
SELECT Batch FROM TableB
And so on. The union removed duplicates.
Then you update like:
Update #MyTableResult SET Column A = ValueA FROM TableA WHERE
#MyTableResult.Batch = TableA.Batch.
After all updates from your tables are done, then you get the desired result.
[ExactReplica].[FilteredOpportunityProduct] Table
Opportunityid baseamount
1 500
1 500
2 600
2 700
[ExactReplica].FilteredOpportunity Table
Opportunityid name
1 ABC
2 CDF
I want to take the maximum baseamount; however, am facing issue when there exists duplicate of the baseamount, how can I take only one record
My Query
select
MaxAmount.[baseamount] ,
c.name
FROM [ExactReplica].FilteredOpportunity c
Left JOIN
(
SELECT opportunityid,
MAX((baseamount)) baseamount
FROM [ExactReplica].[FilteredOpportunityProduct]
GROUP BY opportunityid
) MaxAmount ON c.opportunityid = MaxAmount.opportunityid
inner JOIN
[ExactReplica].[FilteredOpportunityProduct] p ON MaxAmount.opportunityid = p.opportunityid
AND MaxAmount.baseamount = p.baseamount
Try this:
select max(baseamount) baseamount,a.name
from
(select
baseamount, ROW_NUMBER() over (partition by p.opportunityid,baseamount order by p.baseamount desc) rn,
c.name
FROM FilteredOpportunity c
inner JOIN
[FilteredOpportunityProduct] p ON c.opportunityid = p.opportunityid) a
where rn=1
group by a.name
OUTPUT:
baseamount name
500 ABC
700 CDF
Can you try below query for expected result, I have executed the below scripts :
For Table Creation :
CREATE TABLE FILTEREDOPPORTUNITYPRODUCT (
OPPORTUNITYID INT NULL,
BASEAMOUNT VARCHAR(24) NULL
)
CREATE TABLE FILTEREDOPPORTUNITY (
OPPORTUNITYID INT NULL,
NAME VARCHAR(24) NULL
)
Insertion:
INSERT INTO FILTEREDOPPORTUNITYPRODUCT (OPPORTUNITYID,BASEAMOUNT) VALUES
(1,500),(1,500),(2,600),(2,700)
INSERT INTO FILTEREDOPPORTUNITY (OPPORTUNITYID,NAME) VALUES
(1,'ABC'),(2,'CDF')
Selection:
SELECT
A.OPPORTUNITYID,B.NAME,MAX(BASEAMOUNT) AS BASEAMOUNT
FROM FILTEREDOPPORTUNITYPRODUCT AS A
JOIN FILTEREDOPPORTUNITY AS B
ON A.OPPORTUNITYID = B.OPPORTUNITYID
GROUP BY A.OPPORTUNITYID,B.NAME
I need to write a query that returns values from one temp table if another temp table returns no rows.
EDIT: The whole table has a following structure
NAME TYPE DATE VALUE
Washington 1 NULL 1000 <--default value
Washington 2 NULL 750 <--default value
Washington 3 NULL 500 <--default value
Washington 1 04.11.2015 500
Washington 2 04.11.2015 250
Washington 3 04.11.2015 100
Washington 1 07.11.2015 600
Washington 2 07.11.2015 300
Washington 3 07.11.2015 200
Temp table: Name, type, date, value where date IS NULL returns the 'default' values
Temp table : Name, Type, date, value where each unique Name will have 3 types (1,2,3) and each type has a different value, they all have the same date.
When there is no entry for the date column it means that the values should be 'default', which are stored in the same table under rows where date is null
I also have 8 different parameters that determine the Value but I'm only interested in '1' and '2' hence the 'case when'
So what I want to get in the end is:
Select *
from temp1
where date =GETDATE()
And if that doesn't exist I want it to return:
select * from temp2.
I am only interested in getting results for Today, Tomorrow and the day after tomorrow
This is what I've got so far but it's obviously not working.
I would appreciate any help I can get
WITH defaultvalues
AS ( SELECT DISTINCT
n.Name ,
Type ,
Value
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
AND Date IS NULL
),
changedvalue
AS ( SELECT DISTINCT
n.Name ,
type ,
date ,
CASE WHEN d.Date = GETDATE()
AND Parameter = '1' THEN Value
WHEN Parameter = '2' THEN '0'
END AS CAP
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
WHERE Parameter IN ( '1', '2' )
)
SELECT CASE WHEN NOT EXISTS ( SELECT *
FROM changedvalue
WHERE changedvalue.Date = GETDATE() )
THEN ( SELECT *
FROM defaultvalues
)
END
You didn't provide sample data and just basing on your SQL thinking you are only having trouble in the last part:
WITH defaultvalues
AS (
SELECT DISTINCT
n.Name, [type], [date], [Value] AS cap
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id AND
[Date] IS NULL
),
changedvalue
AS (
SELECT DISTINCT
n.Name, [type], [date],
CASE WHEN d.Date = GETDATE() AND
Parameter = '1' THEN [Value]
WHEN Parameter = '2' THEN '0'
END AS CAP
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
WHERE Parameter IN ( '1', '2' )
)
SELECT *
FROM [changedvalue]
UNION
SELECT *
FROM [defaultvalues]
WHERE NOT EXISTS ( SELECT *
FROM [changedvalue] );
It's difficult to read and fully understand your question without sample data, but it seems you are looking to return values from one of two table based on a condition.
One way to achieve this, seeing that you have the same schema for both temp tables, is to simply UNION the results together with the conditional check in the WHERE clause.
I've tried to create a simplified example to show how you can do this, with the below code which is runnable if you copy and paste in to Management Studio.
CREATE TABLE #temp1 (Name VARCHAR(10), [type] VARCHAR(10), [date] DATE, value int)
CREATE TABLE #temp2 (Name VARCHAR(10), [type] VARCHAR(10), [date] DATE, value int)
INSERT INTO #temp1 ( Name, type, date, value )
VALUES ( 'bob', 'male', '2015-03-12', 123)
INSERT INTO #temp2 ( Name, type, date, value )
VALUES ( 'jane', 'female', GETDATE(), 456)
DECLARE #switch BIT = 1
-- with #switch set to 1, #temp1 will be returned
SELECT t1.*
FROM ( SELECT * FROM #temp1
WHERE #switch = 1
UNION
SELECT * FROM #temp2
WHERE #switch = 0
) t1
SET #switch = 0
--with #switch set to 0, #temp2 will be returned
SELECT t1.*
FROM ( SELECT * FROM #temp1
WHERE #switch = 1
UNION
SELECT * FROM #temp2
WHERE #switch = 0
) t1
DROP TABLE #temp1
DROP TABLE #temp2
I'm using the value of #switch on the WHERE condition to determine which table to call in the UNION.
Here is an example:
WITH defaultvalues
AS ( SELECT DISTINCT
n.Name ,
Type ,
Value
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
AND Date IS NULL
),
changedvalue
AS ( SELECT DISTINCT
n.Name ,
type ,
date ,
CASE WHEN d.Date = GETDATE()
AND Parameter = '1' THEN Value
WHEN Parameter = '2' THEN '0'
END AS CAP
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
WHERE Parameter IN ( '1', '2' )
),
final
AS ( SELECT * ,
RANK() OVER ( ORDER BY c ) r
FROM ( SELECT * ,
1 AS c
FROM changedvalue
UNION ALL
SELECT * ,
2 AS c
FROM defaultvalues
) t
)
SELECT *
FROM final
WHERE r = 1
You just union the results with different c column. Then rank on the column c and select where rank equals to 1.
Use Union to combine both answer
WITH defaultvalues
AS ( SELECT DISTINCT
n.Name ,
Type ,
Value
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
AND Date IS NULL
),
changedvalue
AS ( SELECT DISTINCT
n.Name ,
type ,
date ,
CASE WHEN d.Date = GETDATE()
AND Parameter = '1' THEN Value
WHEN Parameter = '2' THEN '0'
END AS CAP
FROM mytable
LEFT JOIN nametable AS n ON mytable.x = r.Id
WHERE Parameter IN ( '1', '2' )
)
( SELECT *
FROM changedvalue
WHERE changedvalue.Date = GETDATE() )
UNION
( SELECT *
FROM defaultvalues
WHERE NOT EXISTS (SELECT 1 FROM changedvalue ))
END