while loop with a multiple tableX union - loops

i want to know please how i can put
union of table 2014 to 2017 only in loop in this query:
select
xxx,
xxx,
xxx,
from (
select
colonne,
colonne,
from CA
left join (
select
xx,
sum(xx) as xx,
xx
from (
select
sum(MONTANT) as MONTANT,
CONCAT(NUM_SIN, CLE_SIN) as cle,
EXER_SIN
from fa
where CD_TYP_CNT='PREV'
group by NUM_SIN, CLE_SIN, EXER_SIN
union
select
sum(MONTANT) as MONTANT,
CONCAT(NUM_SIN, CLE_SIN) as cle,
EXER_SIN
from table2014
where CD_TYP_CNT='PREV'
group by NUM_SIN, CLE_SIN, EXER_SIN
union
select
sum(MONTANT) as MONTANT,
CONCAT(NUM_SIN, CLE_SIN) as cle,
EXER_SIN
from table2015
where CD_TYP_CNT='PREV'
group by NUM_SIN, CLE_SIN, EXER_SIN
union
select
sum(MONTANT) as MONTANT,
CONCAT(NUM_SIN, CLE_SIN) as cle,
EXER_SIN
from table2016
where CD_TYP_CNT='PREV'
group by NUM_SIN, CLE_SIN, EXER_SIN
union
select
sum(MONTANT) as MONTANT,
CONCAT(NUM_SIN, CLE_SIN) as cle,
EXER_SIN
from table2017
where CD_TYP_CNT='PREV'
group by NUM_SIN, CLE_SIN, EXER_SIN ) as tab
group by cle, EXER_SIN) as reglmt on reglmt.cle = CPM.dossiers
left join (
select
CONCAT(colonne, colonne) as cle,
from production
group by colonne, colonne1, colonne3, colonne4) as xx on ptf_CPM.cle = CPM.dossiers
group by xx, xx
) as xx
where vérif <> 0

Related

Show the manufacturer with the 2nd top sales in the year of 2009 and the manufacturer with the 2nd top sales in the year of 2010

I have data in 6 six tables and I have joined 3 tables. I want to return an output in two different columns.
This is what I am doing but going wrong.
SELECT
(SELECT
TOP 2 Manufacturer_name
FROM Fact_Transactions FT
LEFT JOIN DIM_Model DM ON FT.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER MFC ON MFC.IDManufacturer = DM.IDManufacturer
Where DATEPART(Year,date)='2009'
group by Manufacturer_name
Order by SUM (TotalPrice) ) as A,
(SELECT
Top 2 Manufacturer_name
FROM Fact_Transactions FT
LEFT JOIN DIM_Model DM ON FT.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER MFC ON MFC.IDManufacturer = DM.IDManufacturer
Where DATEPART(Year,date)='2010'
group by Manufacturer_name
Order by SUM (TotalPrice)) as B
/*This is showing error => Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. */
CREATE TABLE DIM_MANUFACTURER (
IDManufacturer INT PRIMARY KEY IDENTITY(11, 1),
Manufacturer_Name VARCHAR (20)
)
CREATE TABLE DIM_MODEL (
IDModel INT PRIMARY KEY IDENTITY(101, 1),
Model_Name VARCHAR(20),
Unit_price MONEY ,
IDManufacturer INT REFERENCES DIM_Manufacturer(IDManufacturer)
)
CREATE TABLE FACT_TRANSACTIONS (
IDModel INT REFERENCES DIM_MODEL(IDModel),
IDCustomer INT REFERENCES DIM_CUSTOMER(IDCustomer),
IDLocation INT REFERENCES DIM_LOCATION(IDLocation),
Date DATE REFERENCES DIM_DATE([DATE]),
TotalPrice MONEY,
Quantity INT,
)
INSERT INTO DIM_Manufacturer VALUES
('Apple'), ('Samsung'), ('One Plus'), ('Nokia'), ('Motorola'), ('HTC')
INSERT INTO DIM_MODEL VALUES
('iPhone 4', 377, '11'),
('iPhone 4S', 414, '11'),
('iPhone 5', 456, '11'),
('iPhone 6', 501, '11'),
('iPhone 7', 552, '11'),
('Thunderbolt', 201, '16'),
('C139', 121, '15'), ......
INSERT INTO FACT_TRANSACTIONS VALUES
(130, 10044, 2001, '05/25/2009', 500, 1),
(107, 10043, 2001, '04/16/2003', 126, 1),
(126, 10022, 2005, '11/03/2003', 169, 1),
(111, 10045, 2003, '01/01/2010', 286, 1),
(118, 10012, 2010, '04/21/2007', 149, 1),
(128, 10044, 2005, '10/19/2010', 318, 1),
(124, 10003, 2009, '10/03/2010', 435, 1),
(117, 10002, 2003, '10/13/2010', 54, 1), .....
In this case I think DENSE_RANK() and CTE will be very useful. Here a solution:
WITH cte AS
(
SELECT Manufacturer_name, DATEPART(Year,date) as yr,
DENSE_RANK() OVER (PARTITION BY DATEPART(Year,date) ORDER BY SUM(TotalPrice) DESC) AS Rank
FROM Fact_Transactions FT
LEFT JOIN DIM_Model DM ON FT.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER MFC ON MFC.IDManufacturer = DM.IDManufacturer
group by Manufacturer_name,DATEPART(Year,date)
),
cte2 AS(
SELECT Manufacturer_Name, yr
FROM cte WHERE rank = 2
AND yr IN ('2009','2010')
)
SELECT c.Manufacturer_Name AS Manufacturer_Name_2009
,t.Manufacturer_Name AS Manufacturer_Name_2010
FROM cte2 AS c, cte2 AS t
WHERE c.yr < t.yr;
You can try using row_number()
select X.Manufacturer_name as Manufacturer_name_09,Y.Manufacturer_name as Manufacturer_name_10
from
(
SELECT Manufacturer_name,row_number() over(order by SUM (TotalPrice)) as rn1
FROM Fact_Transactions FT
LEFT JOIN DIM_Model DM ON FT.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER MFC ON MFC.IDManufacturer = DM.IDManufacturer
Where DATEPART(Year,date)=2009
group by Manufacturer_name
)X inner join
(
SELECT Manufacturer_name,row_number() over(order by SUM (TotalPrice)) as rn2
FROM Fact_Transactions FT
LEFT JOIN DIM_Model DM ON FT.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER MFC ON MFC.IDManufacturer = DM.IDManufacturer
Where DATEPART(Year,date)=2010
group by Manufacturer_name
)Y on X.rn1=Y.rn2 and rn1 in (1,2) and rn2 in (1,2)
use this...
SELECT top 1 *
from
(SELECT
TOP 2 Manufacturer_name,
SUM(Quantity ) TQ1
FROM Fact_Transactions T1
LEFT JOIN DIM_Model D1 ON T1.IDModel = D1.IDModel
LEFT JOIN DIM_MANUFACTURER D2 ON D2.IDManufacturer = D1.IDManufacturer
Where DATEPART(Year,date)='2009'
group by Manufacturer_name, Quantity
Order by SUM(Quantity ) DESC ) as A,
(SELECT
Top 2 Manufacturer_name,
SUM(Quantity ) TQ2
FROM Fact_Transactions T2
LEFT JOIN DIM_Model DM ON T2.IDModel = DM.IDModel
LEFT JOIN DIM_MANUFACTURER DM2 ON DM2.IDManufacturer = DM.IDManufacturer
Where DATEPART(Year,date)='2010'
group by Manufacturer_name,Quantity
Order by SUM(Quantity )DESC ) as B
WITH RANK1 AS
(
SELECT MANUFACTURER_NAME,YEAR(DATE) AS YEAR,
DENSE_RANK() OVER (PARTITION BY YEAR(DATE) ORDER BY SUM(TOTALPRICE)DESC) AS RANK
FROM FACT_TRANSACTIONS AS T1
INNER JOIN DIM_MODEL AS T2
ON T1.IDMODEL = T2.IDModel
INNER JOIN DIM_MANUFACTURER AS T3
ON T3.IDManufacturer = T2.IDManufacturer
GROUP BY Manufacturer_Name, YEAR(DATE)
)
SELECT YEAR, MANUFACTURER_NAME
FROM RANK1
WHERE YEAR IN ('2009','2010') AND RANK='2'

Optimizing the sql query that contains CTEs and temptable

I am working on performance optimizing my query. I have implemented two CTEs as well as created a couple of temporary tables. Finally I am writing a combined query that does the union on CTEs and joins with the temp table. I am sharing the code of where I am defining the CTE's and combined query.I have the following query and would like suggestions on what would be the best practice to improve speed.
;with histTbl_CTE
as (
select
a.companyid,
a.periodenddate,
a.pricingdate,
fp.fiscalYear,
fp.fiscalQuarter,
pt.periodtypeId
from (
/* determine the cartesian product of periodenddate and pricingdate, assigning
a periodenddate to every pricing date that is less than the periodenddate */
select
per.companyid,
periodenddate,
pric.pricingdate,
datediff(day, pricingdate, periodenddate) as peqdiffdate
from #PeriodTbl per
join #PricingTbl pric
on (per.companyid = pric.companyid
and per.periodenddate >= pric.pricingdate)
) a
inner join (
/*find the different between the pricing date and the period end date */
select
per.companyid,
periodenddate,
min(datediff(day, pricingdate, periodenddate)) minpeqdiffdate
from
#PeriodTbl per
join #PricingTbl pric
on (per.companyid = pric.companyid
and per.periodenddate >= pric.pricingdate)
group by per.companyid, per.fiscalyear, per.fiscalquarter, periodenddate
)b
on a.companyid = b.companyid
and a.periodenddate = b.periodenddate
and a.peqdiffdate = b.minpeqdiffdate
left join ciqFinPeriod fp on a.companyId = fp.companyId
left join ciqFinInstance fi on (a.periodenddate = fi.periodenddate
and fi.financialPeriodId = fp.financialPeriodId)
left join ciqPeriodType pt on pt.periodTypeId = fp.periodTypeId
where fi.latestforfinancialperiodflag = 1
and latestfilingforinstanceflag = 1
and pt.periodtypeid = 4
group by a.companyid, a.periodenddate, a.pricingdate, fp.fiscalYear, fp.fiscalQuarter, pt.periodtypeid
),
recentTbl_CTE
as (
--/* use the same methodology from above to find the most recent dates */
select
temp.companyId,
max(periodenddate) as periodenddate,
max(peqdate) as pricingDate,
x.adjFY as fiscalYear,
x.adjFQ as fiscalQuarter,
periodTypeId = NULL
from(
select
a.companyId,
a.periodenddate,
a.peqdate,
b.minpeqdiffdate
from(
select
mc.companyId,
mc.pricingDate as periodenddate,
peq.pricingDate as peqdate,
datediff(day, peq.pricingDate, mc.pricingDate) as peqdiffdate
from #MarketTbl mc
join #PricingTbl peq
on (mc.companyId = peq.companyId
and mc.pricingDate >=peq.pricingDate)
group by mc.companyid, mc.pricingDate, peq.pricingDate
) a
inner join (
select
mc.companyId,
mc.pricingdate as periodenddate,
min(datediff(day, peq.pricingDate, mc.pricingDate)) as minpeqdiffdate
from #MarketTbl mc
join #PricingTbl peq
on (mc.companyId = peq.companyId
and mc.pricingDate >= peq.pricingDate)
group by mc.companyid, mc.pricingDate
) b on
a.companyId = b.companyId
and a.periodenddate = b.periodenddate
and a.peqdiffdate = b.minpeqdiffdate
) temp
join #futurePer x on x.companyId = temp.companyId
group by temp.companyid, minpeqdiffdate, adjFY, adjFQ
having minpeqdiffdate = 0
)
/* combine all table and join the data*/
select
combined.companyId,
combined.periodenddate,
combined.dataItemName,
case when combined.dataItemName = 'priceMidUSD' then combined.dataItemidue/exR.currencyRateClose * 1
when combined.dataItemName = 'sharesOutstanding' then combined.dataItemidue
when combined.dataItemName = 'marketcaptrend' then combined.dataItemidue
else combined.dataItemidue/exR.currencyRateClose * 1e6 end as dataItemidue,
combined.fiscalYear,
combined.fiscalQuarter,
combined.periodTypeId,
ctbl.tickerSymbol,
ctbl.exchangeName,
id.dataItemId
from(
select
companyId,
pricingdate,
periodenddate,
currencyId,
dataItemName,
cast(dataItemidue as float) as dataItemidue,
fiscalYear,
fiscalQuarter,
periodTypeId
from(
select
a.companyId,
a.pricingdate,
c.currencyId,
a.periodenddate,
cast(c.priceMid as nvarchar(100)) as priceMidUSD,
cast(d.marketCap as nvarchar(100)) as marketCapUSD,
cast((d.marketCap/nullif(prevmc.prevmarketCap,0)) - 1 as nvarchar(100)) as marketcaptrend,
cast(d.TEV as nvarchar(100)) as TEV,
cast(d.sharesOutstanding as nvarchar(100)) as sharesOutstanding,
a.fiscalYear,
a.fiscalQuarter,
a.periodTypeId
from (
select
companyid,
periodenddate,
pricingdate,
fiscalYear,
fiscalQuarter,
periodtypeId
from histTbl_CTE
union all
select
companyId,
periodenddate,
pricingDate,
fiscalYear,
fiscalQuarter,
periodTypeId
from recentTbl_CTE
)a
join #PricingTbl c
on (
c.pricingdate = a.pricingDate
and c.companyId = a.companyId )
join #MarketTbl d
on (
d.companyId = a.companyId
and d.pricingDate = a.periodenddate)
left join (
select a.companyId,
a.pricingDate,
a.prevperiod,
b.marketcap as prevmarketcap
from(
select
mc.companyid,
mc.pricingdate,
mc.pricingdate -365 as 'prevperiod'
from
ciqMarketCap mc
where
mc.companyid in (select id from #companyId)
) a
inner join (
select
mc.companyId,
mc.pricingdate,
mc.marketcap
from #MarketTbl mc
) b
on (a.companyid = b.companyid
and a.prevperiod = b.pricingdate)
) prevmc
on (prevmc.companyid = d.companyid
and prevmc.pricingdate = d.pricingdate)
group by a.companyid, a.periodenddate, a.pricingDate, a.fiscalYear, a.fiscalQuarter, a.periodtypeid, c.currencyId,
c.pricemid, d.marketCap, d.TEV, d.sharesOutstanding, prevmc.prevperiod, prevmc.prevmarketcap
) c
unpivot
(dataItemidue for dataItemName in
(TEV, marketCapUSD, sharesOutstanding, marketcaptrend, priceMidUSD)
) as unpvt
) combined
join #CompanyInfoTbl ctbl on ctbl.companyId = combined.companyId

How to multi JOIN in SQL Server

I have a query in SQL Server as:
SELECT MD.Author_ID, MD.CoAuthor_ID, MD.Venue_ID, A2P.pid [Paper_ID],
P.abstract_research_area_category_id [Paper_Category_ID],
MD.Year
FROM Merged_Data MD
JOIN sub_aminer_author2paper A2P ON MD.Author_ID = A2P.aid AND
MD.Year = A2P.p_year AND
MD.Venue_ID = A2P.p_venue_vid
JOIN sub_aminer_paper P ON MD.Venue_ID = P.p_venue_vid AND
MD.Year = P.p_year
WHERE MD.Author_ID = 677
Whereas I'm unable to get desired results because unable to join A2P.pid with sub_aminer_paper for extracting [Paper_Category_ID].
How can I join A2P.pid with sub_aminer_paper to have a pid match and extract [Paper_Category_ID] whereas sub_aminer_paper has the field pid?
As per the comment it solved the issue. So the same, I provide the answer for the question:
SELECT MD.Author_ID, MD.CoAuthor_ID, MD.Venue_ID, A2P.pid [Paper_ID],
P.abstract_research_area_category_id [Paper_Category_ID],
MD.Year
FROM Merged_Data MD
JOIN sub_aminer_author2paper A2P ON MD.Author_ID = A2P.aid AND
MD.Year = A2P.p_year AND
MD.Venue_ID = A2P.p_venue_vid
JOIN sub_aminer_paper P ON MD.Venue_ID = P.p_venue_vid AND
MD.Year = P.p_year
WHERE MD.Author_ID = 677 AND A2P.pid = P.pid
Adding the A2P.pid = P.pid in the WHERE clause will solve the problem.
Try This,
SELECT MD.Author_ID, MD.CoAuthor_ID, MD.Venue_ID, A2P.pid [Paper_ID],
P.abstract_research_area_category_id [Paper_Category_ID],
MD.Year
FROM Merged_Data MD
INNER JOIN sub_aminer_author2paper A2P
ON (MD.Author_ID = A2P.aid AND
MD.Year = A2P.p_year AND
MD.Venue_ID = A2P.p_venue_vid)
INNER JOIN sub_aminer_paper P
ON (A2P.pid = P.pid
MD.Venue_ID = P.p_venue_vid AND
MD.Year = P.p_year)
WHERE MD.Author_ID = 677

Oracle to SQL Server syntax change

I'm having some problems with the following query:
select * from
(
select inventory.location, inventory.itemnum as itemnum, item.description as itemdesc,
inventory.minlevel as olevel , invcost.avgcost from inventory join invcost on inventory.itemnum = invcost.itemnum join item on inventory.itemnum = item.itemnum
where inventory.location = 'KHSTORE' AND inventory.itemnum BETWEEN '1221' and '1221' and invcost.location = 'KHSTORE'
) table1
join
(select SUM(balvalues) as balance, itemnum from
(select ib.CURBAL as balvalues, inventory.itemnum as itemnum from invbalances ib join inventory on ib.itemnum = inventory.itemnum and ib.location = inventory.location where inventory.itemnum BETWEEN '1221' and '1221'
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum from matrectrans where itemnum BETWEEN '1221' and '1221' and TRANSDATE >= '05-MAY-2015' and tostoreloc = 'KHSTORE' group by itemnum
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum from matusetrans where itemnum BETWEEN '1221' and '1221' and TRANSDATE >= '05-MAY-2015' and storeloc = 'KHSTORE' group by itemnum
)group by itemnum
) table2 on table1.itemnum = table2.itemnum;
The query runs fine on an Oracle database but when I try to run the same on an SQL Server instance I get the following error:
Msg 156, Level 15, State 1, Line 14
Incorrect syntax near the keyword 'group'.
I'm looking for a way to change this query and make it compatible with both Orace and SQLS, or if not then at least make it run on SQL Server
Try to add alias to subquery:
select * from
(
select inventory.location, inventory.itemnum as itemnum, item.description as itemdesc,
inventory.minlevel as olevel , invcost.avgcost from inventory join invcost on inventory.itemnum = invcost.itemnum join item on inventory.itemnum = item.itemnum
where inventory.location = 'KHSTORE' AND inventory.itemnum BETWEEN '1221' and '1221' and invcost.location = 'KHSTORE'
) table1
join
(select SUM(balvalues) as balance, itemnum from
(select ib.CURBAL as balvalues, inventory.itemnum as itemnum from invbalances ib join inventory on ib.itemnum = inventory.itemnum and ib.location = inventory.location where inventory.itemnum BETWEEN '1221' and '1221'
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum from matrectrans where itemnum BETWEEN '1221' and '1221' and TRANSDATE >= '05-MAY-2015' and tostoreloc = 'KHSTORE' group by itemnum
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum from matusetrans where itemnum BETWEEN '1221' and '1221' and TRANSDATE >= '05-MAY-2015' and storeloc = 'KHSTORE' group by itemnum
) AS t /* HERE */
group by itemnum
) table2 on table1.itemnum = table2.itemnum;
Using CTE for more readability:
WITH table1 AS
(
SELECT inventory.location, inventory.itemnum as itemnum, item.description as itemdesc,
inventory.minlevel as olevel , invcost.avgcost
FROM inventory
JOIN invcost
ON inventory.itemnum = invcost.itemnum
JOIN item
ON inventory.itemnum = item.itemnum
WHERE inventory.location = 'KHSTORE'
AND inventory.itemnum BETWEEN '1221' and '1221'
AND invcost.location = 'KHSTORE'
),
table2 AS
(
SELECT SUM(balvalues) as balance,itemnum
FROM
(SELECT ib.CURBAL as balvalues, inventory.itemnum as itemnum
FROM invbalances ib
JOIN inventory
ON ib.itemnum = inventory.itemnum
AND ib.location = inventory.location
WHERE inventory.itemnum BETWEEN '1221' AND '1221'
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum
FROM matrectrans
WHERE itemnum BETWEEN '1221' AND '1221'
AND TRANSDATE >= '05-MAY-2015'
AND tostoreloc = 'KHSTORE'
GROUP BY itemnum
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum
FROM matusetrans
WHERE itemnum BETWEEN '1221' AND '1221'
AND TRANSDATE >= '05-MAY-2015'
AND storeloc = 'KHSTORE'
GROUP BY itemnum
) AS t /* HERE */
GROUP BY itemnum
)
SELECT *
FROM table1
JOIN table2
ON table2 on table1.itemnum = table2.itemnum;
EDIT
Using CTE no subqueries
WITH table1 AS
(
SELECT inventory.location, inventory.itemnum as itemnum, item.description as itemdesc,
inventory.minlevel as olevel , invcost.avgcost
FROM inventory
JOIN invcost
ON inventory.itemnum = invcost.itemnum
JOIN item
ON inventory.itemnum = item.itemnum
WHERE inventory.location = 'KHSTORE'
AND inventory.itemnum BETWEEN '1221' and '1221'
AND invcost.location = 'KHSTORE'
)
,table2_helper AS
(
SELECT ib.CURBAL as balvalues, inventory.itemnum as itemnum
FROM invbalances ib
JOIN inventory
ON ib.itemnum = inventory.itemnum
AND ib.location = inventory.location
WHERE inventory.itemnum BETWEEN '1221' AND '1221'
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum
FROM matrectrans
WHERE itemnum BETWEEN '1221' AND '1221'
AND TRANSDATE >= '05-MAY-2015'
AND tostoreloc = 'KHSTORE'
GROUP BY itemnum
UNION ALL
SELECT SUM(-1*QUANTITY) , itemnum
FROM matusetrans
WHERE itemnum BETWEEN '1221' AND '1221'
AND TRANSDATE >= '05-MAY-2015'
AND storeloc = 'KHSTORE'
GROUP BY itemnum
)
,table2 AS
(
SELECT SUM(balvalues) as balance,itemnum
FROM table2_helper
GROUP BY itemnum
)
SELECT *
FROM table1
JOIN table2
ON table2 on table1.itemnum = table2.itemnum;

SQL Server Join unequal number of rows

I have data like the below, and would like to see results like below.
The blank spaces should be present in the results. Either Table 2 or Table 3 may contain more rows than the other, and blanks/or/nulls should be in the result.
Table 1
C1=29 (pk) C2=4133
C1=33 (pk) C2=9375
Table 2
C1=29(fk) C2=Adam
C1=29(fk) C2=Bob
C1=29(fk) C2=Chris
C1=29(fk) C2=Dave
C1=33(fk) C2=Eddie
C1=33(fk) C2=Frank
Table 3
C1=29(fk) C2=Helen
C1=29(fk) C2=Joice
C1=33(fk) C2=Karen
C1=33(fk) C2=Laura
C1=33(fk) C2=Mary
Desired result
1.C1=29 1.C2=4133 2.C2=Adam 3.C2=Helen
1.C1=29 1.C2=4133 2.C2=Bob 3.C2=Joice
1.C1=29 1.C2=4133 2.C2=Chris
1.C1=29 1.C2=4133 2.C2=Dave
1.C1=33 1.C2=9375 2.C2=Eddie 3.C2=Karen
1.C1=33 1.C2=9375 2.C2=Frank 3.C2=Laura
1.C1=33 1.C2=9375 3.C2=Mary
Rohit-s query gives --
SELECT t1.col1, t1.col2, t2.col2, t3.col2
FROM dbo.Table1 t1
LEFT JOIN dbo.Table2 t2 ON t1.col1 = t2.col1
LEFT JOIN dbo.Table3 t3 ON t1.col1 = t3.col1
col1 col2 col2 col2
29 4133 Adam Helen
29 4133 Adam Joice
29 4133 Bob Helen
29 4133 Bob Joice
29 4133 Chris Helen
29 4133 Chris Joice
29 4133 Dave Helen
29 4133 Dave Joice
33 9375 Eddie Karen
33 9375 Eddie Laura
33 9375 Eddie Mary
33 9375 Frank Karen
33 9375 Frank Laura
33 9375 Frank Mary
SQL FIDDLE LINK
Can't you just LEFT JOIN all the tables?
Eg:
SELECT t1.C1, t1.C2,t2.C2, t3.C2
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.C1 = t2.C1
LEFT JOIN Table3 t3 on t1.C1 = t3.C1
EDIT :
Based on your edit, and hoping things are ordered:
SELECT t1.C1, t1.C2, t2.C2, t3.C2
FROM Table1 t1
LEFT JOIN (
SELECT C1, C2, row_number() OVER (ORDER BY C1, C2) AS row_num
FROM Table2
) t2 ON t1.C1 = t2.C1
LEFT JOIN (
SELECT C1, C2, row_number() OVER (ORDER BY C1, C2) AS row_num
FROM Table3
) t3 ON t1.C1 = t3.C1 AND t3.row_num = t2.row_num
EDIT 2 :
Assuming everything is in order, (Row_Number and Dense_Rank):
SELECT t1.C1, t1.C2, t2.C2, t3.C2
FROM Table1 t1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table2
) t2 ON t1.C1 = t2.C1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table3
) t3 ON t1.C1 = t3.C1 AND t3.group_num = t2.group_num AND t3.row_num = t2.row_num
EDIT 3:
Dense_Rank, Row_Number, Union
SELECT t1.C1 AS T1C1, t1.C2 AS T1C2, t2.C2 AS T2C2, t3.C2 AS T3C3
FROM Table1 t1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table2
) t2 ON t1.C1 = t2.C1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table3
) t3 ON t1.C1 = t3.C1 AND t3.group_num = t2.group_num AND t3.row_num = t2.row_num
UNION
SELECT t1.C1, t1.C2, t2.C2, t3.C2
FROM Table1 t1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table3
) t3 ON t1.C1 = t3.C1
LEFT JOIN (
SELECT C1, C2, DENSE_RANK() OVER (
ORDER BY C1
) AS group_num, row_number() OVER (
PARTITION BY C1 ORDER BY C1, C2
) AS row_num
FROM Table2
) t2 ON t1.C1 = t2.C1 AND t3.group_num = t2.group_num AND t3.row_num = t2.row_num
ORDER BY T1C1, T1C2, T2C2, T3C3
EDIT 4 :
Dense_Rank, Row_Number, Union, SubQuery, Order By
SELECT *
FROM (
SELECT t1.Col1 AS T1C1, t1.Col2 AS T1C2, t2.Col2 AS T2C2, t3.Col2 AS T3C3
FROM Table1 t1
LEFT JOIN (
SELECT Col1, Col2, DENSE_RANK() OVER (
ORDER BY Col1
) AS group_num, row_number() OVER (
PARTITION BY Col1 ORDER BY Col1, Col2
) AS row_num
FROM Table2
) t2 ON t1.Col1 = t2.Col1
LEFT JOIN (
SELECT Col1, Col2, DENSE_RANK() OVER (
ORDER BY Col1
) AS group_num, row_number() OVER (
PARTITION BY Col1 ORDER BY Col1, Col2
) AS row_num
FROM Table3
) t3 ON t1.Col1 = t3.Col1
AND t3.group_num = t2.group_num
AND t3.row_num = t2.row_num
UNION
SELECT t1.Col1, t1.Col2, t2.Col2, t3.Col2
FROM Table1 t1
LEFT JOIN (
SELECT Col1, Col2, DENSE_RANK() OVER (
ORDER BY Col1
) AS group_num, row_number() OVER (
PARTITION BY Col1 ORDER BY Col1, Col2
) AS row_num
FROM Table3
) t3 ON t1.Col1 = t3.Col1
LEFT JOIN (
SELECT Col1, Col2, DENSE_RANK() OVER (
ORDER BY Col1
) AS group_num, row_number() OVER (
PARTITION BY Col1 ORDER BY Col1, Col2
) AS row_num
FROM Table2
) t2 ON t1.Col1 = t2.Col1
AND t3.group_num = t2.group_num
AND t3.row_num = t2.row_num
) AS SUB
ORDER BY T1C1, T1C2
, CASE WHEN T2C2 IS NULL THEN 1 ELSE 0 END
, CASE WHEN T3C3 IS NULL THEN 1 ELSE 0 END
SQL Fiddle Link

Resources