简体   繁体   中英

SQL JOIN multiplication of a field

i have 3 tables with varios datasets. One of these Tables has more fields like all others.

i have to join it for SQL reporting services. But the problem is, if i join the values, i get the following result:

TABLE 1       TABLE 2
|ID|          |ID|Calls|
|--|          |--|-----|
| 1|          | 2|    7|
| 2|          | 3|    8|
| 3|          | 4|    9|

With a LEFT OUTER JOIN:

|ID|Calls|
|--|-----|
| 1|    7|
| 2|    8|
| 3|    9|

The third table:

|ID|DNIS|Calls|
|--|----|-----|
| 1|4711|    2|
| 1|4712|    3|
| 1|4713|    2|
| 2|4714|    2|
| 2|4715|    3|
| 2|4716|    3|
| 3|4717|    4|
| 3|4718|    3|
| 3|4719|    2|

Together with FULL JOIN

|ID|Calls|DNIS|Calls|
|--|-----|----|-----|
| 1|    7|4711|    2|
| 1|    7|4712|    3|
| 1|    7|4713|    2|
| 2|    8|4714|    2|
| 2|    8|4715|    3|
| 2|    8|4716|    3|
| 3|    9|4717|    4|
| 3|    9|4718|    3|
| 3|    9|4719|    2|

Thr Problem is the mutiplcation iof field Calls. The sums in Report are all 3 times higher. This constuct is totally dynamical and cant catch hardcoded. So I'm looking for a dynamically possibility. What I need is something like this.

|ID|Calls|DNIS|Calls|
|--|-----|----|-----|
| 1|    7|4711|    2|
| 1| NULL|4712|    3|
| 1| NULL|4713|    2|
| 2|    8|4714|    2|
| 2| NULL|4715|    3|
| 2| NULL|4716|    3|
| 3|    9|4717|    4|
| 3| NULL|4718|    3|
| 3| NULL|4719|    2|

Do you have an idea?

My testquery looks like this DECLARE @t1 TABLE ( id INT )

INSERT INTO @t1 SELECT 1
INSERT INTO @t1 SELECT 2
INSERT INTO @t1 SELECT 3

SELECT * FROM @t1

DECLARE @t2 TABLE (
id INT
,calls INT
)

INSERT INTO @t2 SELECT 1,3
INSERT INTO @t2 SELECT 2,4
INSERT INTO @t2 SELECT 3,5

DECLARE @t3 TABLE (
    id INT
    ,DNIS INT
    ,cnt INT
)
INSERT INTO @t3 SELECT 1,1,3
INSERT INTO @t3 SELECT 1,2,4
INSERT INTO @t3 SELECT 1,3,5

INSERT INTO @t3 SELECT 2,1,3
INSERT INTO @t3 SELECT 2,2,4
INSERT INTO @t3 SELECT 2,3,5

INSERT INTO @t3 SELECT 3,1,3
INSERT INTO @t3 SELECT 3,2,4
INSERT INTO @t3 SELECT 3,3,5

SELECT
    t1.id
    ,t2.calls
    ,t3.DNIS
    ,t3.CNT
FROM
@t1 as t1
FULL JOIN
@t3 as t3
on t1.id = t3.id
LEFT OUTER JOIN
@t2 as t2
on t1.id = t2.id

If you want your query to return nulls for Calls all but the first row with a given ID, you could do something like this:

  -- Column names must be unique.  You have two columns for Calls, so I'm 
  -- renaming them here as Calls1 and Calls2.
  ;
  WITH data1 AS (
     select  ID
             Calls1
          ,  DNIS
          ,  Calls2
     from [your query]
  )
  ,  data2 as (
     select *
        ,   RowNumber = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY DNIS) 
     from   data1
 )
 select  ID
    ,    Calls = CASE WHEN RowNumber = 1 THEN Calls1 ELSE Null END
    ,    DNIS
    ,    Calls2
 from    data2   

With out using two CTE's

SELECT 
        T1.id,
        CASE 
            WHEN ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY T3.DNIS)= 1 THEN T2.calls 
            ELSE NULL 
        END AS Calls
    ,   T3.DNIS
    ,   T3.cnt

FROM @t1 T1
     FULL JOIN @t3 T3 ON T3.id = T1.id
     LEFT JOIN @t2 T2 ON T2.id = T1.id

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