简体   繁体   中英

Join two tables multiple times on same column with a lookup table in between

This has probably been answered but, its hard to search for this question, as you can see in my confusing title.

Anyhow, I hope this example will help:

表和期望的结果

The tricky part is the one to many relationship in the parameter lookup table.

Ive tried using multiple joins and aliases resulting in a hugh number of rows since Im getting every 'amount' for every 'price'.

SELECT paraval.month, paraval.value as amount, paraval2.value as price, trade.position
FROM trade
INNER JOIN parameter para on trade.tID=para.tID and para.name = 'amount'
INNER JOIN parametervalues paraval on para.pID=paraval.pID

INNER JOIN parameter para2 on trade.tID=para2.tID and para2.name = 'price'
INNER JOIN parametervalues paraval2 on para2.pID=paraval2.pID
WHERE trade.type = 'cert'

Guessing I need sub-queries, but not sure where to place them.

EDIT add some SQL code structure :

CREATE TABLE #Trade  
(
    tID             int PRIMARY KEY,  
    type            varchar(50),
    position        int
 );  
CREATE TABLE #Parameter  
(
    pID             int PRIMARY KEY, 
    tID             int, 
    name            varchar(50)
);  
CREATE TABLE #ParameterValue  
(
    pID         int,  
    smonth      varchar(50),
    value       varchar(50));  


INSERT INTO #Trade 
SELECT 1, 'stock', 1
UNION
SELECT 2, 'stock', 2
UNION
SELECT 3, 'cert', 3

INSERT INTO #Parameter 
SELECT 1,1,'amount'
UNION
SELECT 2,1,'price'
UNION
SELECT 3,2,'amount'
UNION
SELECT 4,2,'price'
UNION
SELECT 5,3,'amount'
UNION
SELECT 6,3,'price'

INSERT INTO #ParameterValue
SELECT 1,1,'5'
UNION
SELECT 2,1,'500'
UNION
SELECT 3,1,'15'
UNION 
SELECT 4,1,'300'
UNION
SELECT 5,1,'5'
UNION
SELECT 5,2,'10'
UNION
SELECT 5,3,'5'
UNION
SELECT 6,1,'100'
UNION
SELECT 6,2,'200'
UNION 
SELECT 6,3,'300'

-- SELECT * FROM #Trade

-- SELECT * FROM #Parameter

-- SELECT * FROM #ParameterValue


DROP TABLE #Trade
DROP TABLE #Parameter
DROP TABLE #ParameterValue

I think the best way for build your excepted output and relevant schema you have to use pivot with dynamic sql because in next day it possible to have some new values it's the principal of your structure.

But i think this query can be respond :

SELECT paraval.month, (case when para. name = 'amount' then max(paraval.value) else null end)as amount, (case when para. name = 'price' then  max(paraval.value) else null end) as price, max(trade.position) as position 
FROM trade
INNER JOIN parameter para on trade.tID=para.tID 
INNER JOIN parametervalues paraval on para.pID=paraval.pID
WHERE trade.type = 'cert'
Group by paraval.month 

EDIT correction off previous query :

CREATE TABLE #Trade  
(
    tID             int PRIMARY KEY,  
    type            varchar(50),
    position        int
 );  
CREATE TABLE #Parameter  
(
    pID             int PRIMARY KEY, 
    tID             int, 
    name            varchar(50)
);  
CREATE TABLE #ParameterValue  
(
    pID         int,  
    smonth      varchar(50),
    value       varchar(50));  


INSERT INTO #Trade 
SELECT 1, 'stock', 1
UNION
SELECT 2, 'stock', 2
UNION
SELECT 3, 'cert', 3

INSERT INTO #Parameter 
SELECT 1,1,'amount'
UNION
SELECT 2,1,'price'
UNION
SELECT 3,2,'amount'
UNION
SELECT 4,2,'price'
UNION
SELECT 5,3,'amount'
UNION
SELECT 6,3,'price'

INSERT INTO #ParameterValue
SELECT 1,1,'5'
UNION
SELECT 2,1,'500'
UNION
SELECT 3,1,'15'
UNION 
SELECT 4,1,'300'
UNION
SELECT 5,1,'5'
UNION
SELECT 5,2,'10'
UNION
SELECT 5,3,'5'
UNION
SELECT 6,1,'100'
UNION
SELECT 6,2,'200'
UNION 
SELECT 6,3,'300'


/***/
-- Perform select 
/***/
SELECT t.tID, paraval.smonth, MAX(case when para.name = 'amount' then paraval.value else null end)as amount, MAX(case when para.name = 'price' then  paraval.value else null end) as price, max(T.position) as position 
FROM #Trade T
INNER JOIN #Parameter para on T.tID=para.tID 
INNER JOIN #ParameterValue paraval on para.pID=paraval.pID
Group by T.tId, paraval.smonth
/***/

DROP TABLE #Trade
DROP TABLE #Parameter
DROP TABLE #ParameterValue

RESULT :

tID smonth  amount  price   position
1   1       5       500     1
2   1       15      300     2
3   1       5       100     3
3   2       10      200     3
3   3       5       300     3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM