A problem with a simple join taking too long to finish - sql

I´m having trouble identifying who to fix this simple join.
SELECT A.CUSER,
COUNT(*) AS QTD
FROM BO_PRODUCTCONFIG A WITH (NOLOCK)
INNER JOIN BO_PRICER001 B WITH (NOLOCK)
ON (
A.CIDBRANCH = B.CIDBRANCH
OR B.CIDBRANCH IS NULL
)
AND (
A.CIDPRODUCT = B.CIDPRODUCT
OR B.CIDPRODUCT IS NULL
)
My problem is, after adding the column B.CIDPRODUCT IS NULL this query takes hours to finish.
table BO_PRICER001 rows 286537
table BO_PRODUCTCONFIG rows 7934844
on the table BO_PRICER001 exists 15329 rows with null
with B.CIDPRODUCT IS NULL the live query show this plan:
and without this column the plan is:
I already try to force an index and switch to a subquery but the problem continues.
if possible, I really appreciate a help.
Sample of data from PRICER001
CIDPRICE CIDCOMPANY CIDBRANCH CIDTABLEPRICE CIDCOMMISSIONGROUP CIDPRODUCT CIDPERIODPAYMENT DENDDATEVALIDITY DSTARTDATEVALIDITY NINCREASEPERCENT LACTIVE DLASTUPDATE NINCREASEPERCENTORIG
XPTO0319 XPTO NULL NULL NULL NULL 319 9999-12-31 00:00:00.000 2018-08-27 00:00:00.000 2.100 1 2020-10-07 05:07:37.917 21.000
XPTO0321 XPTO NULL NULL NULL NULL 321 9999-12-31 00:00:00.000 2014-08-06 00:00:00.000 2.100 1 2020-10-07 05:07:37.917 21.000
XPTO0326 XPTO NULL NULL NULL NULL 326 9999-12-31 00:00:00.000 2018-08-27 00:00:00.000 3.150 1 2020-10-07 05:07:37.917 31.500
XPTO0328 XPTO NULL NULL NULL NULL 328 9999-12-31 00:00:00.000 2014-08-06 00:00:00.000 3.150 1 2020-10-07 05:07:37.917 31.500
XPTO0345 XPTO NULL NULL NULL NULL 345 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 4.530 1 2020-10-07 05:07:37.917 45.300
XPTO0390 XPTO NULL NULL NULL NULL 390 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 9.130 1 2020-10-07 05:07:37.917 91.300
XPTO0412 XPTO NULL NULL NULL NULL 412 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 11.500 1 2020-10-07 05:07:37.917 115.000
XPTO0428 XPTO NULL NULL NULL NULL 428 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 2.640 1 2020-10-07 05:07:37.917 26.400
XPTO0460 XPTO NULL NULL NULL NULL 460 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 5.690 1 2020-10-07 05:07:37.917 56.900
XPTO0515 XPTO NULL NULL NULL NULL 515 9999-12-31 00:00:00.000 2020-05-29 00:00:00.000 13.900 1 2020-10-07 05:07:37.917 139.000
Sample of data from PRODUCTCONFIG
CIDPRODUCTCONFIG CIDPRODUCT CIDPRODUCTMARKET CIDPRODUCTBUSINESS CIDPRODUCTLINE CIDPRODUCTGROUP CIDPRODUCTSUBGROUP CIDREGION CIDBRANCH CIDTEAM CIDTERRITORY LACTIVE LFLAG DLASTUPDATE CUSER CTPDCA
5840992036 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2036 1 NULL 2020-10-07 00:49:15.837 2036 1
5840992037 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2037 1 NULL 2020-10-07 00:49:15.837 2037 1
5840992038 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2038 1 NULL 2020-10-07 00:49:15.837 2038 1
5840992039 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2039 1 NULL 2020-10-07 00:49:15.837 2039 1
5840992040 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2040 1 NULL 2020-10-07 00:49:15.837 2040 1
5840992041 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2041 1 NULL 2020-10-07 00:49:15.837 2041 1
5840992042 584099 XPTO XPTO XPTO ACM FFK NULL 1402 NULL 2042 1 NULL 2020-10-07 00:18:20.783 2042 1
5840992044 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2044 1 NULL 2020-10-07 00:49:15.837 2044 1
5840992045 584099 XPTO XPTO XPTO ACM FFK NULL 1685 NULL 2045 1 NULL 2020-10-07 00:49:15.837 2045 1
5840992048 584099 XPTO XPTO XPTO ACM FFK NULL 1686 NULL 2048 1 NULL 2020-10-07 00:50:20.223 2048 1

OR kills performance. A typical workaround are multiple LEFT JOIN. Perhaps:
I´m having trouble identifying who to fix this simple join.
SELECT pc.CUSER,
COUNT(*) AS QTD
FROM BO_PRODUCTCONFIG pc LEFT JOIN
BO_PRICER001 prbp
ON pc.CIDBRANCH = prbp.CIDBRANCH AND
pc.CIDPRODUCT = prbp.CIDPRODUCT LEFT JOIN
BO_PRICER001 prb
ON pc.CIDBRANCH = prb.CIDBRANCH AND
prbp.CIDPRODUCT IS NULL LEFT JOIN
BO_PRICER001 prp
ON prp.CIDBRANCH IS NULL AND
prp.CIDPRODUCT = pc.CIDPRODUCT LEFT JOIN
BO_PRICER001 pr
ON prp.CIDBRANCH IS NULL AND
prp.CIDPRODUCT IS NULL
WHERE prbp.CIDBRANCH is not null OR prb.CIDBRANCH is not null OR pr.CIDPRODUCT is not null or pr.<some other column> is not null;

Related

Rank based on conditional Partitions in Snowflake

I have a table1 which has a d_date column and table_2 which has start and end_dates columns and a code column , after joining this matches with the first table on at start and end date values :
So I got below result after joining these two tables as:
`
with cte as (select table_a.d_date, table_2.start_date, table_2.end_date,
table_2.code from
table_a left join table_2 on table_a.d_date = table_2.start_date order by d_date
asc)
select * from cte where year(d_date) =2023
D_DATE
START_DATE
END_DATE
Code
2023-01-01
NULL
NULL
NULL
2023-01-02
NULL
NULL
NULL
2023-01-03
NULL
NULL
NULL
2023-01-04
2023-01-04
2023-01-31
C
2023-01-04
2023-01-04
2023-01-31
D
2023-01-04
2023-01-04
2023-01-31
E
2023-01-04
2023-01-04
2023-01-31
M
2023-01-05
NULL
NULL
NULL
2023-01-06
NULL
NULL
NULL
2023-01-07
NULL
NULL
NULL
2023-01-08
NULL
NULL
NULL
2023-01-09
NULL
NULL
NULL
2023-01-10
NULL
NULL
NULL
2023-01-11
NULL
NULL
NULL
2023-01-12
NULL
NULL
NULL
2023-01-13
NULL
NULL
NULL
2023-01-14
NULL
NULL
NULL
2023-01-15
NULL
NULL
NULL
2023-01-16
NULL
NULL
NULL
2023-01-17
NULL
NULL
NULL
2023-01-18
NULL
NULL
NULL
2023-01-19
NULL
NULL
NULL
2023-01-20
NULL
NULL
NULL
2023-01-21
NULL
NULL
NULL
2023-01-22
NULL
NULL
NULL
2023-01-23
NULL
NULL
NULL
2023-01-24
NULL
NULL
NULL
2023-01-25
NULL
NULL
NULL
2023-01-26
NULL
NULL
NULL
2023-01-27
NULL
NULL
NULL
2023-01-28
NULL
NULL
NULL
2023-01-29
NULL
NULL
NULL
2023-01-30
NULL
NULL
NULL
2023-01-31
NULL
NULL
NULL
2023-02-01
2023-02-01
2023-02-28
M
2023-02-01
2023-02-01
2023-02-28
E
2023-02-01
2023-02-01
2023-02-28
D
2023-02-01
2023-02-01
2023-02-28
C
2023-02-02
NULL
NULL
NULL
I need to generate sequence over the d_date column of table_a as shown below, here the start of a sequnce should begin when start_date is matching with d_date and it should continue once it has reached end_date .
so sequence of numbers ranging between start_date and end_date
pls note 32,33 , 34 sequnce is coming from previous month
D_DATE
START_DATE
END_DATE
Code
RES_SEQ
2023-01-01
NULL
NULL
NULL
32
2023-01-02
NULL
NULL
NULL
33
2023-01-03
NULL
NULL
NULL
34
2023-01-04
2023-01-04
2023-01-31
C
NULL
2023-01-04
2023-01-04
2023-01-31
D
1
2023-01-04
2023-01-04
2023-01-31
E
Null
2023-01-04
2023-01-04
2023-01-31
M
Null
2023-01-05
NULL
NULL
NULL
2
2023-01-06
NULL
NULL
NULL
3
2023-01-07
NULL
NULL
NULL
4
2023-01-08
NULL
NULL
NULL
5
2023-01-09
NULL
NULL
NULL
6
2023-01-10
NULL
NULL
NULL
7
2023-01-11
NULL
NULL
NULL
8
2023-01-12
NULL
NULL
NULL
9
2023-01-13
NULL
NULL
NULL
10
2023-01-14
NULL
NULL
NULL
11
2023-01-15
NULL
NULL
NULL
12
2023-01-16
NULL
NULL
NULL
13
2023-01-17
NULL
NULL
NULL
14
2023-01-18
NULL
NULL
NULL
15
2023-01-19
NULL
NULL
NULL
16
2023-01-20
NULL
NULL
NULL
17
2023-01-21
NULL
NULL
NULL
18
2023-01-22
NULL
NULL
NULL
19
2023-01-23
NULL
NULL
NULL
20
2023-01-24
NULL
NULL
NULL
21
2023-01-25
NULL
NULL
NULL
22
2023-01-26
NULL
NULL
NULL
23
2023-01-27
NULL
NULL
NULL
24
2023-01-28
NULL
NULL
NULL
25
2023-01-29
NULL
NULL
NULL
26
2023-01-30
NULL
NULL
NULL
27
2023-01-31
NULL
NULL
NULL
28
2023-02-01
2023-02-01
2023-02-28
M
Null
2023-02-01
2023-02-01
2023-02-28
E
Null
2023-02-01
2023-02-01
2023-02-28
D
1
2023-02-01
2023-02-01
2023-02-28
C
Null
2023-02-02
NULL
NULL
NULL
2

SQL-SERVER Filter By ROW_NUMBER and Another Condition

I have this SQL-SERVER Query:
SELECT t.Id,
t.ClientTemplateFieldId,
t.ClientTemplateFieldOptionId,
t.TextData,
t.NumberData,
t.DateTimeData,
t.TreatmentDate,
t.rn FROM
(
SELECT tfd.Id,
tfd.ClientTemplateFieldId,
tfd.ClientTemplateFieldOptionId,
tfd.TextData,
tfd.NumberData,
tfd.DateTimeData,
t.TreatmentDate,
ROW_NUMBER() OVER (PARTITION BY tfd.ClientTemplateFieldId ORDER BY t.TreatmentDate DESC) as rn
FROM TemplateFieldData tfd
INNER JOIN
Treatment t ON tfd.TreatmentId = t.Id
WHERE tfd.IsDeleted = 0 AND
t.IsDeleted = 0 AND
tfd.ClientId = 2 AND
t.ClientId = 2 AND
t.PatientId = 6003720 AND
tfd.ClientTemplateFieldId IN
(1873,1874,1875,1876)
) AS t
--WHERE CLAUSE...
And this is the table result of the above query:
Id ClientTemplateFieldId ClientTemplateFieldOptionId TextData NumberData DateTimeData TreatmentDate rn
4324 1873 1627 NULL NULL NULL 2021-01-14 09:00:00.000 1
4325 1873 1628 NULL NULL NULL 2021-01-14 09:00:00.000 2
4326 1873 1631 NULL NULL NULL 2021-01-14 09:00:00.000 3
4322 1873 1627 NULL NULL NULL 2021-01-13 09:00:00.000 4
4323 1873 1629 NULL NULL NULL 2021-01-13 09:00:00.000 5
4320 1873 1626 NULL NULL NULL 2021-01-12 22:00:00.000 6
4321 1873 1630 NULL NULL NULL 2021-01-12 22:00:00.000 7
4338 1874 NULL SomeTxt NULL NULL 2021-01-14 09:00:00.000 1
4330 1874 NULL SomeTxt NULL NULL 2021-01-13 09:00:00.000 2
4327 1874 NULL SomeTxt NULL NULL 2021-01-12 22:00:00.000 3
4328 1875 NULL NULL 10.00 NULL 2021-01-12 22:00:00.000 1
4331 1876 1634 NULL NULL NULL 2021-01-13 09:00:00.000 1
4329 1876 1632 NULL NULL NULL 2021-01-12 22:00:00.000 2
What should I put in the Where Clause in order to retrieve all rows with row_number = 1 and
also if there is a row with the same TreatmentDate and ClientTemplateFieldId as of one of the rows where
row_number = 1, I need that row to.
Meaning I need this result:
Id ClientTemplateFieldId ClientTemplateFieldOptionId TextData NumberData DateTimeData TreatmentDate rn
4324 1873 1627 NULL NULL NULL 2021-01-14 09:00:00.000 1
4325 1873 1628 NULL NULL NULL 2021-01-14 09:00:00.000 2
4326 1873 1631 NULL NULL NULL 2021-01-14 09:00:00.000 3
4338 1874 NULL SomeTxt NULL NULL 2021-01-14 09:00:00.000 1
4328 1875 NULL NULL 10.00 NULL 2021-01-12 22:00:00.000 1
4331 1876 1634 NULL NULL NULL 2021-01-13 09:00:00.000 1
You could use MAX() window function instead of ROW_NUMBER() to get all the rows with the latest TreatmentDate for each ClientTemplateFieldId:
SELECT t.Id,
t.ClientTemplateFieldId,
t.ClientTemplateFieldOptionId,
t.TextData,
t.NumberData,
t.DateTimeData,
t.TreatmentDate,
t.rn
FROM (
SELECT tfd.Id,
tfd.ClientTemplateFieldId,
tfd.ClientTemplateFieldOptionId,
tfd.TextData,
tfd.NumberData,
tfd.DateTimeData,
t.TreatmentDate,
ROW_NUMBER() OVER (PARTITION BY tfd.ClientTemplateFieldId ORDER BY t.TreatmentDate DESC) AS rn,
MAX(t.TreatmentDate) OVER (PARTITION BY tfd.ClientTemplateFieldId) AS max_TreatmentDate
FROM TemplateFieldData tfd
INNER JOIN
Treatment t ON tfd.TreatmentId = t.Id
WHERE tfd.IsDeleted = 0 AND
t.IsDeleted = 0 AND
tfd.ClientId = 2 AND
t.ClientId = 2 AND
t.PatientId = 6003720 AND
tfd.ClientTemplateFieldId IN
(1873,1874,1875,1876)
) AS t
WHERE t.TreatmentDate = t.max_TreatmentDate
ROW_NUMBER() is not actually needed but I kept it in my query just in case you want it in the results.
If I assume that this entire query result (without the where condition) is created as a View called T for example, you can do the following:
SELECT *
FROM T
WHERE T.rn = 1
OR EXISTS
(SELECT 1 FROM T as T2
WHERE T2.TreatmentDate = T.TreatmentDate
AND T2.ClientTemplateFieldId = T.ClientTemplateFieldId
AND T.rn != 1
AND T2.rn = 1)

Need to keep column 1 the same, but PIVOT the second column dynamically

I have a query that looks at data that has been inserted into a TEMP table (not including as there is sensitive information in that table).
I can get the information I need, but I need to organize it better.
The output data displays as
trac_id CONTACT_DATE
040 2017-02-20 00:00:00.000
059 2017-03-08 00:00:00.000
001 2017-03-01 00:00:00.000
001 2017-03-08 00:00:00.000
001 2017-03-13 00:00:00.000
001 2017-03-16 00:00:00.000
001 2017-03-16 00:00:00.000
001 2017-03-17 00:00:00.000
001 2017-03-22 00:00:00.000
001 2017-03-23 00:00:00.000
001 2017-03-23 00:00:00.000
001 2017-03-24 00:00:00.000
001 2017-03-27 00:00:00.000
001 2017-03-27 00:00:00.000
001 2017-03-30 00:00:00.000
001 2017-03-31 00:00:00.000
068 2017-02-13 00:00:00.000
067 2017-01-24 00:00:00.000
060 2017-02-08 00:00:00.000
060 2017-03-07 00:00:00.000
011 2017-02-16 00:00:00.000
011 2017-03-01 00:00:00.000
011 2017-03-23 00:00:00.000
011 2017-03-30 00:00:00.000
005 2017-02-16 00:00:00.000
005 2017-03-18 00:00:00.000
005 2017-03-08 00:00:00.000
013 2017-03-08 00:00:00.000
013 2017-03-13 00:00:00.000
013 2017-03-16 00:00:00.000
013 2017-03-16 00:00:00.000
013 2017-03-17 00:00:00.000
013 2017-03-22 00:00:00.000
013 2017-03-23 00:00:00.000
013 2017-03-24 00:00:00.000
013 2017-03-27 00:00:00.000
013 2017-03-27 00:00:00.000
013 2017-03-30 00:00:00.000
013 2017-03-30 00:00:00.000
013 2017-03-31 00:00:00.000
043 2017-02-03 00:00:00.000
Right now I'm using the following query to get this:
SELECT
spl.trac_id
,pev.CONTACT_DATE
FROM
#SAMHSA_PAT_LIST spl
INNER JOIN dbo.IDENTITY_ID_VIEW iiv
ON iiv.IDENTITY_ID=spl.MRN
LEFT JOIN dbo.PAT_ENC_VIEW pev
ON pev.PAT_ID = iiv.PAT_ID
LEFT JOIN dbo.PAT_ENC_RSN_VISIT_VIEW rsn
ON rsn.PAT_ENC_CSN_ID=pev.PAT_ENC_CSN_ID
WHERE
pev.CONTACT_DATE >= #Start_Date
AND pev.CONTACT_DATE < #End_Date
AND pev.APPT_STATUS_C IN ( 2 , 6 , 8 , 9 )
AND rsn.ENC_REASON_ID = 590;
What I need to get is to have 2+n columns. I won't know exactly how many but a quick look shows trac_id 001 with 14 entries. So if that was the max number I would need the columns to be trac_id, mm_1, mm_2, mm_3, mm_4,...,mm_14 without hard coding the number of columns I want to PIVOT into. My problem is that in all of the posts and documentation I've seen about using PIVOT I see the data inserted into a table beforehand and then usually the entire table is PIVOT'ed.
Is it possible to only PIVOT the second column and if so, how would I do this?
So, I was able to figure out part of my solution based on a couple posts and your help #Jakub_Ojmucianski. What I've come up with is the following, but it's only halfway there and I'm sure I've made a mistake:
DECLARE #SQL VARCHAR(MAX)='',#PVT_COL VARCHAR(MAX)='';
SELECT #PVT_COL =#PVT_COL + '[mm_'+CAST(ROW_NUMBER() OVER(ORDER BY (SELECT
1)) AS VARCHAR(4))+'],'
FROM #medmtemp
SELECT #PVT_COL = LEFT(#PVT_COL,LEN(#PVT_COL)-1)
SELECT #SQL =
'SELECT * FROM (
SELECT trac_id, Contact ,''mm_''+CAST(ROW_NUMBER() OVER(ORDER BY (SELECT 1))
AS VARCHAR(4)) AS COL_NME
FROM #medmtemp
)AS A
PIVOT
(
MAX(Contact) FOR COL_NME IN ('+#PVT_COL+')
)PVT'
EXEC (#SQL)
I see the following (Just including the first three new rows):
trac_id mm_1 mm_2 mm_3 mm_4 mm_5 mm_6 mm_7 mm_8 mm_9 mm_10 mm_11 mm_12 mm_13 mm_14 mm_15 mm_16 mm_17 mm_18 mm_19 mm_20
1 3/1/2017 3/8/2017 3/13/2017 3/16/2017 3/16/2017 3/17/2017 3/22/2017 3/23/2017 3/23/2017 3/24/2017 3/27/2017 3/27/2017 3/30/2017 3/31/2017 NULL NULL NULL NULL NULL NULL
5 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 2/16/2017 3/18/2017 3/8/2017 NULL NULL NULL
8 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 3/8/2017 3/23/2017 3/30/2017
you can do something like that:
IF(OBJECT_ID('tempdb..#myTable') IS NOT null)
DROP TABLE #myTable
IF(OBJECT_ID('tempdb..#pivotColumn') IS NOT null)
DROP TABLE #pivotColumn
CREATE TABLE #myTable
(
trac_id varchar(3),
CONTACT_DATE datetime
)
INSERT INTO #myTable VALUES
('040', '2017-02-20 00:00:00.000'),
('059' ,'2017-03-08 00:00:00.000'),
('001' ,'2017-03-01 00:00:00.000'),
('001' ,'2017-03-08 00:00:00.000'),
('001' ,'2017-03-13 00:00:00.000'),
('001' ,'2017-03-16 00:00:00.000'),
('001' ,'2017-03-17 00:00:00.000')
SELECT ROW_NUMBER() OVER(ORDER BY CONTACT_DATE) as rowNumber,CONTACT_DATE INTO #pivotColumn FROM(
SELECT DISTINCT CONTACT_DATE FROM #myTable
) AS source
DECLARE #columns VARCHAR(MAX)=''
DECLARE #curentRow int = 1;
WHILE #curentRow <= (SELECT MAX(rowNumber) from #pivotColumn)
BEGIN
SET #columns+= '['+(SELECT Cast(CONTACT_DATE as varchar) FROM #pivotColumn WHERE rowNumber = #curentRow)+'],'
SET #curentRow += 1;
END
SET #columns = SUBSTRING(#columns,1,LEN(#columns)-1)
DECLARE #code Varchar(MAX) =
'
SELECT * FROM #myTable
Pivot
(
COUNT(trac_id) FOR CONTACT_DATE IN (
'
+
#columns
+
'
)
) as p'
EXEC(#code)
But be aware of grouping function in dynamic pivot - you have to decide what you want to do with those data? Sum it, count it?
Regards

Distinct query for SQL Server needed

I am pulling data with this query in SQL Server
SELECT DISTINCT
DOC.TPID,
DOC.TYPE,
DOC.DOCNO,
O211.PONO,
H210.INVDATE,
H210.INVNO,
H210.EQPMTINIT,
H210.EQPMTNO,
D214.DESTIMATED,
D214.DACTUAL,
DOC.CDATETIME
FROM [databasename].[dbo].[DOC]
JOIN [databasename].[dbo].[IN_211_HDR] H211 ON DOC.[TRANNO] = H211.TRANNO
JOIN [databasename].[dbo].[IN_211_ORD] O211 ON H211.TRANNO = O211.TRANNO
JOIN [databasename].[dbo].[IN_210_HDR] H210 ON DOCNO = H210.BOLNO
JOIN [databasename].[dbo].[IN_214_HDR] H214 ON H211.BOLNO = H214.SHPID
JOIN [databasename].[dbo].[IN_214_DTL] D214 ON H214.TRANNO = D214.TRANNO
WHERE
[TPID] = 'DSV' AND doc.[STATUSERP] = ''
ORDER BY
CDATETIME DESC
This will return the following result set.
O211.PONO D214.DESTIMATED
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-04-20 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-02 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-03 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-18 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8203444 106843 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106843 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106847 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106847 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 108380 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 108380 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
I need to have it so that it only returns rows with a unique O211.PONO. The only difference between those rows is the date but I need to only return one row for each unique O211.PONO number. It should take the one with the latest date in the D214.DESTIMATED field.
The easiest way is with row_number():
with t as (
<your query here without the order by>
)
select t.*
from (select t.*,
row_number() over (partition by PONO order by DESTIMATED desc) as seqnum
from t
) t
where seqnum = 1;

Comparing and Merging two tables in SQL Server 2005

I have two scripts which produce the following two tables(t1 and t2).
Is there a way of merging t1 and t2 to make t3?
The first 5 rows of each table have the same value in the first column (Number).
However in t1 the columns PreOpOrg and PreOpModality are populated but in t2 they are NULL, and vice versa for columns PostOpOrg and PostOpModality.
So the merge would populate the columns with the non-NULL values from each table (t1 and t2). For the rows in t1 and t2 that only appear in one table then they should appear in t3 as if a normal UNION were being attempted.
Unfortunately while I am working in SQL2005 the script needs to be compatible with SQL2000.
Many thanks.
--t1
Number DateOfBirth PreOpOrg PreOpModality PostOpOrg PostOpModality DiagDate
8643576344 01/04/1935 00:00:00 RBA11 2 NULL NULL 04/09/2012 00:00
2345680016 01/01/1960 00:00:00 RBA11 4 NULL NULL 11/11/2011 00:00
6955934252 20/01/1980 00:00:00 RBA11 4 NULL NULL 22/08/2012 00:00
2234582369 28/12/1940 00:00:00 RBA11 5 NULL NULL 02/11/2011 00:00
9477684368 01/02/1959 00:00:00 RBA11 5 NULL NULL 02/01/2014 00:00
--t2
Number DateOfBirth PreOpOrg PreOpModality PostOpOrg PostOpModality DiagDate
8643576344 01/04/1935 00:00:00 NULL NULL RBA11 2 04/09/2012 00:00
2345680016 01/01/1960 00:00:00 NULL NULL RBA11 2 11/11/2011 00:00
6955934252 20/01/1980 00:00:00 NULL NULL RN325 5 22/08/2012 00:00
2234582369 28/12/1940 00:00:00 NULL NULL RBA11 5 02/11/2011 00:00
9477684368 01/02/1959 00:00:00 NULL NULL RBA11 5 02/01/2014 00:00
0000001564 01/01/1970 00:00:00 NULL NULL RBA11 2 08/08/2012 00:00
4225127842 11/07/1948 00:00:00 NULL NULL RBA11 2 10/09/2011 00:00
0909093842 01/07/1957 00:00:00 NULL NULL RN325 5 26/08/2009 00:00
8528528855 05/12/1969 00:00:00 NULL NULL RBA11 5 25/10/2010 00:00
1000001367 05/05/1950 00:00:00 NULL NULL RBA11 5 08/04/2011 00:00
2234573513 30/11/1946 00:00:00 NULL NULL RN325 5 20/04/2011 00:00
1000001566 18/03/1951 00:00:00 NULL NULL RBA11 5 20/03/2012 00:00
0000001600 01/01/1970 00:00:00 NULL NULL RBA11 5 28/03/2013 00:00
1000001621 12/12/1950 00:00:00 NULL NULL RBA11 5 06/12/2013 00:00
--t3
Number DateOfBirth PreOpOrg PreOpModality PostOpOrg PostOpModality DiagDate
8643576344 01/04/1935 00:00:00 RBA11 2 RBA11 2 04/09/2012 00:00
2345680016 01/01/1960 00:00:00 RBA11 4 RBA11 2 11/11/2011 00:00
6955934252 20/01/1980 00:00:00 RBA11 4 RN325 5 22/08/2012 00:00
2234582369 28/12/1940 00:00:00 RBA11 5 RBA11 5 02/11/2011 00:00
9477684368 01/02/1959 00:00:00 RBA11 5 RBA11 5 02/01/2014 00:00
0000001564 01/01/1970 00:00:00 NULL NULL RBA11 2 08/08/2012 00:00
4225127842 11/07/1948 00:00:00 NULL NULL RBA11 2 10/09/2011 00:00
0909093842 01/07/1957 00:00:00 NULL NULL RN325 5 26/08/2009 00:00
8528528855 05/12/1969 00:00:00 NULL NULL RBA11 5 25/10/2010 00:00
1000001367 05/05/1950 00:00:00 NULL NULL RBA11 5 08/04/2011 00:00
2234573513 30/11/1946 00:00:00 NULL NULL RN325 5 20/04/2011 00:00
1000001566 18/03/1951 00:00:00 NULL NULL RBA11 5 20/03/2012 00:00
0000001600 01/01/1970 00:00:00 NULL NULL RBA11 5 28/03/2013 00:00
1000001621 12/12/1950 00:00:00 NULL NULL RBA11 5 06/12/2013 00:00
Considering to your data and requirement to run on SQL 2000 I am providing you below solution.
Please let me know in case you face any issue. For my convenience I have added only few records from your sample. If you are using SQL Server 2008 or higher version you can use of COALESCE function as explained here.
create table t1
(
Number VARCHAR(10),
DateOfBirth DATETIME,
PreOpOrg VARCHAR(10),
PreOpModality INT,
PostOpOrg VARCHAR(10),
PostOpModality INT,
DiagDate DATETIME
)
create table t2
(
Number VARCHAR(10),
DateOfBirth DATETIME,
PreOpOrg VARCHAR(10),
PreOpModality INT,
PostOpOrg VARCHAR(10),
PostOpModality INT,
DiagDate DATETIME
)
INSERT INTO T1 values (8643576344,'01/04/1935 00:00:00','RBA11',2,NULL,NULL,'04/09/2012 00:00'),
(2345680016,'01/01/1960 00:00:00','RBA11',4,NULL,NULL,'11/11/2011 00:00')
INSERT INTO T2 values ('8643576344','01/04/1935 00:00:00',NULL,NULL,'RBA11',2,'04/09/2012 00:00'),
('0000001564','01/01/1970 00:00:00',NULL,NULL,'RBA11',2,'08/08/2012 00:00'),
('2345680016','01/01/1960 00:00:00',NULL,NULL,'RBA11',2,'11/11/2011 00:00' )
SELECT * FROM T1
SELECT * FROM T2
SELECT CASE WHEN T1.Number IS NOT NULL THEN T1.Number ELSE T2.NUMBER END AS Number,
CASE WHEN T1.DateOfBirth IS NOT NULL THEN T1.DateOfBirth ELSE T2.DateOfBirth END AS DateOfBirth,
CASE WHEN T1.PreOpOrg IS NOT NULL THEN T1.PreOpOrg ELSE T2.PreOpOrg END AS PreOpOrg,
CASE WHEN T1.PreOpModality IS NOT NULL THEN T1.PreOpModality ELSE T2.PreOpModality END AS PreOpModality,
CASE WHEN T1.PostOpOrg IS NOT NULL THEN T1.PostOpOrg ELSE T2.PostOpOrg END AS PostOpOrg,
CASE WHEN T1.PostOpModality IS NOT NULL THEN T1.PostOpModality ELSE T2.PostOpModality END AS PostOpModality,
CASE WHEN T1.DiagDate IS NOT NULL THEN T1.DiagDate ELSE T2.DiagDate END AS DiagDate
FROM T1
RIGHT JOIN T2 ON T1.Number = T2.Number
Another solution can be
SELECT
ISNULL(T1.Number, T2.NUMBER) AS Number
,ISNULL(T1.DateOfBirth, T2.DateOfBirth) AS DateOfBirth
,ISNULL(T1.PreOpOrg, T2.PreOpOrg) AS PreOpOrg
,ISNULL(T1.PreOpModality, T2.PreOpModality) AS PreOpModality
,ISNULL(T1.PostOpOrg, T2.PostOpOrg) AS PostOpOrg
,ISNULL(T1.PostOpModality, T2.PostOpModality) AS PostOpModality
,ISNULL(T1.DiagDate, T2.DiagDate) AS DiagDate
FROM T1
RIGHT JOIN T2
ON T1.Number = T2.Number