简体   繁体   English

在 SQL 服务器中使用具有多个条件的 INNER JOIN

[英]Using INNER JOIN with multiple conditions in SQL server

I have the below data and I need to join the two tables and get the results so that it converts PRICE1_VALUE and PRICE2_VALUE to EURO in the single record.我有以下数据,我需要加入这两个表并获得结果,以便它将 PRICE1_VALUE 和 PRICE2_VALUE 转换为单个记录中的 EURO。

SELECT
PRODUCT,
CASE 
        WHEN PRICE1_VALUE ='EURO'
            THEN PRICE1_VALUE
            ELSE [T1.PRICE1_VALUE]*T2.EXCHANGE_VALUE
        END AS [PRICE1_VALUE],
CASE
        WHEN PRICE2_VALUE ='EURO'
            THEN PRICE2_VALUE
            ELSE [T1.PRICE2_VALUE]*T2.EXCHANGE_VALUE
        END AS [PRICE2_VALUE],
T1.START_DATE
FROM TABLE1 T1
INNER JOIN TABLE2 T2
ON      YEAR (T1.START_DATE)= YEAR(T2.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T2.START_DATE)
AND     (T1.PRICE1_CURRENCY= T2.FROM_CODE
    OR   T1.PRICE2_CURRENCY= T2.FROM_CODE
    )
WHERE TO_CODE = 'EURO'

With this query its returning two separate records against each record, which I can understand is because of the way I have joined the two tables.使用此查询,它针对每条记录返回两条单独的记录,我可以理解这是因为我连接这两个表的方式。 Could you please help understand how I could fix it?你能帮助理解我如何解决它吗?

I understand its this condition causing it to return multiple records.我了解它的这种情况导致它返回多条记录。

AND     (T1.PRICE1_CURRENCY= T2.FROM_CODE
    OR   T1.PRICE2_CURRENCY= T2.FROM_CODE
    )

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

You must replace the OR-join with another join to TABLE2:您必须将 OR-join 替换为 TABLE2 的另一个连接:

SELECT
PRODUCT,
CASE 
        WHEN PRICE1_VALUE ='EURO'
            THEN PRICE1_VALUE
            ELSE [T1.PRICE1_VALUE]*T2.EXCHANGE_VALUE
        END AS [PRICE1_VALUE],
CASE
        WHEN PRICE2_VALUE ='EURO'
            THEN PRICE2_VALUE
            ELSE [T1.PRICE2_VALUE]*T3.EXCHANGE_VALUE
        END AS [PRICE2_VALUE],
T1.START_DATE
FROM TABLE1 T1
INNER JOIN TABLE2 T2 -- maybe LEFT JOIN
ON      YEAR (T1.START_DATE)= YEAR(T2.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T2.START_DATE)
AND     T1.PRICE1_CURRENCY= T2.FROM_CODE
INNER JOIN TABLE2 T3 -- maybe LEFT JOIN
ON      YEAR (T1.START_DATE)= YEAR(T3.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T3.START_DATE)
AND     T1.PRICE2_CURRENCY= T3.FROM_CODE

If I understand correctly, you can do what you want with two left join s:如果我理解正确,你可以用两个left join做你想做的事:

SELECT PRODUCT,
       (CASE WHEN PRICE1_CURRENCY ='EURO'
             THEN PRICE1_VALUE
              ELSE T1.PRICE1_VALUE * T2_1.EXCHANGE_VALUE
        END) AS PRICE1_VALUE,
       (CASE WHEN PRICE2_CURRENCY = 'EURO'
             THEN PRICE2_VALUE
             ELSE T1.PRICE2_VALUE * T2_2.EXCHANGE_VALUE
        END ) AS PRICE2_VALUE
       T1.START_DATE
FROM TABLE1 T1 LEFT JOIN
     TABLE2 T2_1
     ON YEAR(T1.START_DATE) = YEAR(T2_1.START_DATE) AND
        MONTH(T1.START_DATE) = MONTH(T2_1.START_DATE) AND
        T1.PRICE1_CURRENCY = T2_1.FROM_CODE LEFT JOIN
     TABLE2 T2_2
     ON YEAR(T1.START_DATE) = YEAR(T2_2.START_DATE) AND
        MONTH(T1.START_DATE) = MONTH(T2_2.START_DATE) AND
        T1.PRICE2_CURRENCY = T2_2.FROM_CODE 
WHERE T2_1.FROM_CODE IS NOT NULL OR T2_2.FROM_CODE IS NOT NULL;

Note: Do not overuse square braces.注意:不要过度使用方括号。 Your use looked incorrect in your code and was unnecessary.您的使用在您的代码中看起来不正确并且是不必要的。

I don't think your query is doing what you want it to.我不认为您的查询正在执行您想要的操作。

The specific answer to your question - "Why do I get two results?"您问题的具体答案 - “为什么我得到两个结果?” is that the OR clause matches a the "1 to 1" conversion row in your table:是 OR 子句匹配表中的“1 到 1”转换行:

OR T1.PRICE2_CURRENCY= T2.FROM_CODE或 T1.PRICE2_CURRENCY= T2.FROM_CODE

A better version of your query would be:您的查询的更好版本是:

SELECT
PRODUCT,
T1.PRICE1_VALUE *P1_CONVERSION_RATE.EXCHANGE_VALUE AS [PRICE1_VALUE],
T1.PRICE2_VALUE *P2_CONVERSION_RATE.EXCHANGE_VALUE AS [PRICE2_VALUE],
T1.START_DATE
FROM TABLE1 T1
INNER JOIN TABLE2 P1_CONVERSION_RATE
ON      YEAR (T1.START_DATE)= YEAR(T2.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T2.START_DATE)
AND     T1.PRICE1_CURRENCY= T2.FROM_CODE
INNER JOIN TABLE2 P2_CONVERSION_RATE
ON      YEAR (T1.START_DATE)= YEAR(T2.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T2.START_DATE)
AND     T1.PRICE2_CURRENCY= T2.FROM_CODE

If you want EURO as a result only, you can just add in the end:如果您只想要 EURO 作为结果,您可以在最后添加:

where T2.TO_CODE='EURO'

However, if you want to see both prices for each product, stick to Gordon's solution.但是,如果您想查看每种产品的两种价格,请坚持使用 Gordon 的解决方案。

you can do using distinct你可以使用不同的

SELECT  distinct
PRODUCT,
CASE 
        WHEN PRICE1_VALUE ='EURO'
            THEN PRICE1_VALUE
            ELSE [T1.PRICE1_VALUE]*T2.EXCHANGE_VALUE
        END AS [PRICE1_VALUE],
CASE
        WHEN PRICE2_VALUE ='EURO'
            THEN PRICE2_VALUE
            ELSE [T1.PRICE2_VALUE]*T2.EXCHANGE_VALUE
        END AS [PRICE2_VALUE],
T1.START_DATE
FROM TABLE1 T1
INNER JOIN TABLE2 T2
ON      YEAR (T1.START_DATE)= YEAR(T2.START_DATE)
AND     MONTH(T1.START_DATE)= MONTH(T2.START_DATE)
AND     (T1.PRICE1_CURRENCY= T2.FROM_CODE
    OR   T1.PRICE2_CURRENCY= T2.FROM_CODE
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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