SQL JOIN 问题 - 复杂 SELECT 作为 JOIN 条件

SQL JOIN issue - complex SELECT as JOIN Condition

我正在尝试连接两个具有字符键的 table,我需要使用 SELECT 查询来形成其中一个连接条件。这是数据:

Table M

MKey OtherData
---- ---------
ABCD kjjh
EFGH oioo
IJKL uhdjdhu
MNOP isdid
QRST lkuh

Table FUN

FUNKey  BinaryField
------  -----------
ABCD/GGG 1
ABCD/KKK 0
ABCD/MMM 1
EFGH/ABC 1
IJKL/DDD 1
IJKL/VVV 1
IJKL/XXX 0
MNOP/AAA 1
NMOP/DEF 1
NMOP/FFF 1
QRST/SSS 0

table 中没有唯一字段或数字字段,也没有其他字段可以加入。

这是我使用 JOIN 的起始查询:

Select MKey,Otherdata from M
LEFT OUTER JOIN FUN
ON M.MKey = left(FUNKey, CHARINDEX ('/', FUNKey) -1)
AND FUN.BinaryData=1

Returns

ABCD kjjh
ABCD kjjh
EFGH oioo
IJKL uhdjdhu
ABCD kjjh
MNOP isdid
MNOP isdid
MNOP isdid
MNOP isdid

我需要它 return 的是 M 中的一行,其中 FUN 中有一行以 "MKey" 开头并具有 FUN.BinaryData=1,如下所示:

ABCD kjjh
EFGH oioo
IJKL uhdjdhu
MNOP isdid

我在 FUN.FUNKey 列上尝试了 GROUP BY、MIN、MAX 但没有成功。

如果我使用单独使用 ROW_NUMBER、OVER 和 PARTITION 等的查询,我会得到我想要加入的内容:

(Select M_Code from

(Select left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1) as M_Code
,row_number () over (partition by left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1) 
order by left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1))

as rn
from FUN F
where F.BinaryData=1
) tmp

Where rn=1
)

Returns:

ABCD
EFGH
IJKL
MNOP

所以我认为我很好,直到我尝试将它用于连接:

The following code gives me:
"Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as an
expression."

Select MKey,Otherdata from M
LEFT OUTER JOIN ON M.MKEY = 

(Select M_Code from

(Select left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1) as M_Code
,row_number () over (partition by left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1) 
order by left(F.FUNKey, CHARINDEX ('/', F.FUNKey) -1))

as rn
from FUN F
where F.BinaryData=1
) tmp

Where rn=1
)

是否有一个简单的解决方案可以在我丢失的连接中使用 SELECT 的结果,或者我是否试图(再次)除以零?

环境是 MS SQL 20012

有点不清楚你想要完成什么,但也许这就是你要找的东西:

SELECT MKey, Otherdata 
FROM M
LEFT OUTER JOIN (
    SELECT DISTINCT 
      LEFT(FUNKey, CHARINDEX ('/', FUNKey) -1) FUNKEY
    , BinaryData 
    FROM FUN
) F ON M.MKey = F.FUNKEY AND F.BinaryData = 1;

这会 return:

MKey                 Otherdata
-------------------- --------------------
ABCD                 kjjh
EFGH                 oioo
IJKL                 uhdjdhu
MNOP                 isdid
QRST                 lkuh

如果您不想要最后一行(BinaryData = 0),则将连接条件中的 AND 改为 WHERE。

declare @Table1 TABLE 
    ([MKey] varchar(4), [OtherData] varchar(7))
;

INSERT INTO @Table1
    ([MKey], [OtherData])
VALUES
    ('ABCD', 'kjjh'),
    ('EFGH', 'oioo'),
    ('IJKL', 'uhdjdhu'),
    ('MNOP', 'isdid'),
    ('QRST', 'lkuh')
;
declare @Table2 TABLE 
    ([FUNKey] varchar(8), [BinaryField] int)
;

INSERT INTO @Table2
    ([FUNKey], [BinaryField])
VALUES
    ('ABCD/GGG', 1),
    ('ABCD/KKK', 0),
    ('ABCD/MMM', 1),
    ('EFGH/ABC', 1),
    ('IJKL/DDD', 1),
    ('IJKL/VVV', 1),
    ('IJKL/XXX', 0),
    ('MNOP/AAA', 1),
    ('NMOP/DEF', 1),
    ('NMOP/FFF', 1),
    ('QRST/SSS', 0)

;
;with CTE AS(
select A.MKey,
      A.OtherData,
      BinaryField,
ROW_NUMBER()OVER(PARTITION BY OtherData ORDER BY (SELECT NULL) )RN from (
Select MKey,Otherdata,BinaryField  
 from @Table1 M
       LEFT OUTER JOIN @Table2 FUN
 ON M.MKey = left(FUNKey, CHARINDEX ('/', FUNKey) -1)
AND FUN.BinaryField=1)A )
Select MKey,
       OtherData
 from CTE 
where RN = 1 
AND BinaryField IS NOT NULL
ORDER BY Mkey

我认为你们都让这比现在更难了

Select distinct M.MKey, M.Otherdata 
from M
JOIN FUN
     ON M.MKey = left(FUNKey, CHARINDEX ('/', FUNKey) -1)
     AND FUN.BinaryData = 1