October 5, 2011 at 5:11 pm
I need a query
Data is in millions. I am just presenting you some data
TableA
Col1 Col2 Col3 Col4
1 121 21/10/2002 Row1
1 231 25/11/2002 Row2
1 341 28/12/2002 Row3
2 121 18/08/2003 Row4
2 231 19/09/2003 Row5
2 341 21/11/2003 Row6
TableB
Col1 Col2 Col3
1 21% 21/10/2002 Row7
1 32% 02/12/2002 Row8
1 45% 01/01/2003 Row9
2 11% 18/08/2003 Row10
2 42% 20/10/2003 Row11
2 85% 01/01/2004 Row12
If you observe the data,
Row1 Date= Row7 date
Row2 Date= between Row7 Date and Row8 Date
Row3 Date= between Row8 Date and Row9 Date
Row4 Date= Row10 date
Row5 Date= between Row10 Date and Row11 Date
Row6 Date= between Row11 Date and Row12 Date
I need to populate Col4 in TableA with Col2 in TableB if above conditions are true with same Col1.
If above conditions satisfied,
O/p looks like:
TableA
Col1 Col2 Col3 Col4
1 121 21/10/2002 21%
1 231 25/11/2002 21%
1 341 28/12/2002 32%
2 121 18/08/2003 11%
2 231 19/09/2003 11%
2 341 21/11/2003 42%
October 5, 2011 at 5:18 pm
My bad!
Structure is not showed properly.
TableA: Col1-> 1..2
Col2 -> 121...341
Col3-> Date's
Col4 -> empty
TableB:
Col1 -> 1..2
Col2-> Percentages
Col3-> Date's
October 5, 2011 at 5:40 pm
If you would post your table definitions, sample data in a readily consumable format, you increase the chance of someone assisting you with a tested answer.
To do as above, please read the article whose link in the first line of my signature block. The article contains easily useable T-SQL code to produce the information in a readily consumable format
October 5, 2011 at 7:36 pm
USE [AdventureWorks]
GO
CREATE TABLE [dbo].[tblA](
[ID] [smallint] NULL,
[Code] [varchar](50) NULL,
[Date] [date] NULL
)
CREATE TABLE [dbo].[tblB](
[ID] [smallint] NULL,
[Percentage] [varchar](50) NULL,
[EffectiveDate] [date] NULL
)
GO
INSERT INTO [AdventureWorks].[dbo].[tblA]
([ID]
,[Code]
,[Date])
VALUES
(1,121,'2002-02-10'),
(1,231,'2002-03-15'),
(1,322,'2002-04-20'),
(2,241,'2003-05-12'),
(2,561,'2003-07-27'),
(2,871,'2003-09-22')
GO
INSERT INTO [AdventureWorks].[dbo].[tblB]
([ID]
,[Percentage]
,[EffectiveDate])
VALUES
(1,22,'2002-02-10'),
(1,24,'2002-03-30'),
(1,15,'2002-04-25'),
(2,83,'2003-05-12'),
(2,56,'2003-08-30'),
(2,72,'2003-10-10')
GO
I need to add a extracolumn to my tblA with Percentage column in tblB
Here in tblB,Percentage column for ID 1
22 is effective from '2002-02-10'to '2002-03-30'
24 is effective from '2002-03-30'to '2002-04-25'
15 is effective from '2002-04-25'
For example,
2nd row in tblA Date is '2002-03-15', It will fall in Percentage 22
Output should look like:
1 121 '2002-02-10' 22
1 231 '2002-03-15' 22
1 322 '2002-04-20' 24
2 241 '2003-05-12' 83
2 561 '2003-07-27' 83
2 871 '2003-09-22' 56
October 5, 2011 at 11:37 pm
try this
Select *
,(Select top 1 [Percentage] from [tblB] B Where B.EffectiveDate<=A.Date
Order By .EffectiveDate Desc) as [ColB]
from [tblA] A
MI
http://raresql.com
October 5, 2011 at 11:46 pm
How about this?
SELECT A.* , CrsAppOutput.Percentage
FROM tblA A
CROSS APPLY
(
SELECT TOP 1 B.Percentage
FROM tblB B
WHERE B.ID = A.ID
AND ( B.EffectiveDate <= A.Date )
ORDER BY B.EffectiveDate DESC
) CrsAppOutput
With proper indexing, this code perform very good 🙂 But i sense, Jeff's Quirky Update might dash everything out..let me see if i could code that..
October 6, 2011 at 12:13 am
Thanks for answering..
Could you please tell me....how query looks if I need to append Effectivedate column(tblB) to the result set...
October 6, 2011 at 12:28 am
Like this..
SELECT A.* , CrsAppOutput.Percentage , CrsAppOutput.EffectiveDate
FROM tblA A
CROSS APPLY
(
SELECT TOP 1 B.Percentage , B.EffectiveDate
FROM tblB B
WHERE B.ID = A.ID
AND ( B.EffectiveDate <= A.Date )
ORDER BY B.EffectiveDate DESC
) CrsAppOutput
select * from tblB
select * from tblA
October 9, 2011 at 3:56 pm
For that business logics , yoy could use the simple below update query:
update TableA SET COL4=COL2 from ( select col2,col3 from TableB )AS s INNER JOIN TableA on TableA.COL3=S.COL3
[font="Arial Black"]Performance Guard[/font]
[font="Courier New"]Just ask me to get 0 sec for all queries[/font]
October 9, 2011 at 4:32 pm
Performace Guard (Shehap) (10/9/2011)
For that business logics , yoy could use the simple below update query:update TableA SET COL4=COL2 from ( select col2,col3 from TableB )AS s INNER JOIN TableA on TableA.COL3=S.COL3
Shehap... Did you try that code against the given data?
--Jeff Moden
Change is inevitable... Change for the better is not.
October 9, 2011 at 11:27 pm
You are right Jeif, i have missed one business case, therefore to match up perfectly with the output results , we could go with the udpate statements in consequence :
update TableA SET COL4= s.COL2 from ( select cal2 , tableB.col1 from tableB inner join (select col1,min(col3) as col3_min from TableB group by col1) as S1 on S1.col1=TableB .col1 )AS S INNER JOIN TableA on TableA.COL1=S.COL1
update TableA SET COL4=case when table1.col3>col3_max then s.COL2 end from ( select cal2 , tableB.col1,col3_max from tableB inner join( select col1,max(col3) as col3_max from TableB group by col1) as S1 on S1.col1=TableB .col1 )AS S INNER JOIN TableA on TableA.COL1=S.COL1
[font="Arial Black"]Performance Guard[/font]
[font="Courier New"]Just ask me to get 0 sec for all queries[/font]
October 9, 2011 at 11:34 pm
Performace Guard (Shehap) (10/9/2011)
You are right Jeif, i have missed one business case, therefore to match up perfectly with the output results , we could go with the udpate statements in consequence :update TableA SET COL4= s.COL2 from ( select cal2 , tableB.col1 from tableB inner join (select col1,min(col3) as col3_min from TableB group by col1) as S1 on S1.col1=TableB .col1 )AS S INNER JOIN TableA on TableA.COL1=S.COL1
update TableA SET COL4=case when table1.col3>col3_max then s.COL2 end from ( select cal2 , tableB.col1,col3_max from tableB inner join( select col1,max(col3) as col3_max from TableB group by col1) as S1 on S1.col1=TableB .col1 )AS S INNER JOIN TableA on TableA.COL1=S.COL1
Really ??? :w00t: Man, that query will be very very slow, as the requirement is to run the query over a million row table.. hmmm. even the query i sent will perform slow..
October 10, 2011 at 5:21 am
Performace Guard (Shehap) (10/9/2011)
You are right Jeif, i have missed one business case, ...
Heh... I have 4 letters in my name and you did me the dishonor of mispelling it. 😉
--Jeff Moden
Change is inevitable... Change for the better is not.
October 10, 2011 at 6:11 am
If huge data entity of records , we have to look for indexing enhancements since that code below could run sufficiently even for millions of record ..
For the needed indexes :
Create nonclustered index TableB_index1 on TableB (col3 asc) include (col2)
Create nonclustered index TableB_index2 on TableB (col3 asc) include (col1)
Create nonclustered index TableA_index1 on TableA (col1 asc) include (col2)
[font="Arial Black"]Performance Guard[/font]
[font="Courier New"]Just ask me to get 0 sec for all queries[/font]
October 10, 2011 at 6:21 am
Also More enhancement
1-You could create those indexes below
Create nonclustered index TableB_index1 on TableB (col3 asc) include (col2)
Create nonclustered index TableB_index2 on TableB (col3 asc) include (col1)
Create nonclustered index TableA_index1 on TableA (col3 asc) include (col4)
2-Then apply page compression for those indexes.
3-Disable any relevant triggers while update
4-If needed for more enhancements, you could apply an appropriate schema partitioning model to get advantage of I/O parallel processing for huge date entity
[font="Arial Black"]Performance Guard[/font]
[font="Courier New"]Just ask me to get 0 sec for all queries[/font]
Viewing 15 posts - 1 through 14 (of 14 total)
You must be logged in to reply to this topic. Login to reply