我正在加入两个表,或者更确切地说是一个查询和多个字段的子查询。因此,对于第一个查询中的每个PK,我可以从第二个子查询中获取一个或多个记录。有没有办法只从两个查询中返回TOP 1匹配?
示例:
SELECT t1.ID, a.FieldID, a.Field1, a.Field2, a.Field3, a.Field4
FROM Table1 as t1
INNER JOIN
(SELECT t2.FieldID, t2.Field1, t2.Field2, t3.Field3, t3.Field4 FROM Table2 as t2
INNER JOIN Table3 as t3 ON t2.ID=t3.IDFrom2) as a
ON t1.IDFor2=a.FieldID
WHERE LEN(a.[Field1]) < 80 AND LEN(a.Field3) < 60
AND (CHARINDEX(LTRIM(RTRIM(REPLACE(t1.Field1,' ',''))),LTRIM(RTRIM(REPLACE(a.Field1,' ',''))))>0 OR CHARINDEX(LTRIM(RTRIM(REPLACE(a.Field1,' ',''))),LTRIM(RTRIM(REPLACE(t1.Field1,' ',''))))>0 OR t1.Field1 IS NULL)
AND (CHARINDEX(LTRIM(RTRIM(t1.Field2)),LTRIM(RTRIM(a.Field2)))>0 or CHARINDEX(LTRIM(RTRIM(a.Field2)),LTRIM(RTRIM(t1.Field2)))>0 OR t1.Field2 IS NULL)
AND (CHARINDEX(LTRIM(RTRIM(t1.Field3)),LTRIM(RTRIM(a.Field3)))>0 OR t1.Field3 IS NULL)
AND CHARINDEX(LTRIM(RTRIM(t1.Field4)),LTRIM(RTRIM(a.Field4)))>0
子查询
SELECT t2.FieldID, t2.Field1, t2.Field2, t3.Field3, t3.Field4 FROM Table2 as t2
INNER JOIN Table3 as t3 ON t2.ID=t3.IDFrom2
返回一些记录(具有相同的t2.Field),当单独运行时,它们与Table1有关系,只是过滤t2.FieldID等于Table1中的特定IDFor2
但是当两个查询连接在一起并在各个字段上匹配时,我获得两倍的记录,因为它为每个t1.ID返回一些重复项。如何修改我的查询以便每个t1.ID只检索一条记录(TOP 1)?
P.S。不幸的是,我无法提供真实数据,因为它是保密的。
更新:
子查询
SELECT t2.FieldID, t2.Field1, t2.Field2, t3.Field3, t3.Field4 FROM Table2 as t2
INNER JOIN Table3 as t3 ON t2.ID=t3.IDFrom2
返回以下两个表:
Table2 Table3
_____________________________________ _________________
abc123 Company1 Industry1 def def 300 0.67
abc123 Company1 Industry1 fgh fgh 500 0.81
abc123 Company1 Industry1 hjk hjk 80 0.0045
abc123 Company2 Industry2 lmn lmn 250 0.003
abc123 NULL NULL vck vck 500 0.81
Table1
______________________________________________________
10001 abc123 1 Comp Industry1 300 0.67
10002 abc123 2 NULL NULL 500 0.81
10003 abc123 3 NULL NULL 80 0.0045
10004 abc123 4 Company2 Industr 250 0.003
10005 abc123 5 NULL NULL 500 0.81
我需要在关键字上组合Table2和Table3数据,这些数据是def,fgh等......
然后我需要将Table1与合并的Table2和Table3相匹配,然后对#34; rich&#34;进行排序。表1从表2和表3中提取的数据。我想得到类似的结果:
10001 abc123 Company1 Industry1 300 0.67
10002 abc123 Company1 Industry1 500 0.81
10003 abc123 Company1 Industry1 80 0.0045
10004 abc123 Company2 Industry2 250 0.003
10005 abc123 Company2 Industry2 500 0.81
相反,我得到了一种笛卡尔积:
10001 abc123 1 Company1 Industry1 300 0.67
10002 abc123 2 Company1 Industry1 500 0.81
10002 abc123 2 Company1 Industry2 500 0.81
10003 abc123 3 Company1 Industry1 80 0.0045
10004 abc123 4 Company2 Industry2 250 0.003
10005 abc123 5 Company2 Industry2 500 0.81
10005 abc123 5 Company2 Industry1 500 0.81
更新2:
我使用了Ionic的方法并且它起作用了。我修改了我的查询以使用row_number和partition:
SELECT * FROM
(SELECT t1.ID, a.FieldID, a.Field1, a.Field2, a.Field3, a.Field4
FROM Table1 as t1
INNER JOIN
(SELECT t2.FieldID, t2.Field1, t2.Field2, t3.Field3, t3.Field4 FROM Table2 as t2
INNER JOIN Table3 as t3 ON t2.ID=t3.IDFrom2) as a
ON t1.IDFor2=a.FieldID
WHERE LEN(a.[Field1]) < 80 AND LEN(a.Field3) < 60
AND (CHARINDEX(LTRIM(RTRIM(REPLACE(t1.Field1,' ',''))),LTRIM(RTRIM(REPLACE(a.Field1,' ',''))))>0 OR CHARINDEX(LTRIM(RTRIM(REPLACE(a.Field1,' ',''))),LTRIM(RTRIM(REPLACE(t1.Field1,' ',''))))>0 OR t1.Field1 IS NULL)
AND (CHARINDEX(LTRIM(RTRIM(t1.Field2)),LTRIM(RTRIM(a.Field2)))>0 or CHARINDEX(LTRIM(RTRIM(a.Field2)),LTRIM(RTRIM(t1.Field2)))>0 OR t1.Field2 IS NULL)
AND (CHARINDEX(LTRIM(RTRIM(t1.Field3)),LTRIM(RTRIM(a.Field3)))>0 OR t1.Field3 IS NULL)
AND CHARINDEX(LTRIM(RTRIM(t1.Field4)),LTRIM(RTRIM(a.Field4)))>0) as b
WHERE b.rn=1
答案 0 :(得分:2)
您可以在子查询上运行它并为每个t1.ID
运行它以检索第一个值。但另一方面,您可以尝试使用ROW_NUMBER()
解决此问题。
这是一个小例子,假设您有两个表t1
和t2
。您只想在t2
中第一次出现。
SELECT *
FROM t1
INNER JOIN (
SELECT t2.id, t2.name, t2.create_date,
ROW_NUMBER() OVER(PARTITION BY t2.id ORDER BY t2.create_date) as rn
FROM t2
) as t2
ON t1.id = t2.id
WHERE t2.rn = 1
在这种情况下,这将基于create_date
(在您的情况下,您的逻辑位于句子&#34;第一次出现&#34;)和分区(组)基于{{1 }}
然后你加入它,只关注t2.id
答案 1 :(得分:0)
您可以在CTE功能的帮助下完成。您可以在CTE中创建select语句,然后将CTE与主表连接以获得您喜欢的结果
WITH A
(
SELECT t2.id, t2.name, t2.create_date,
ROW_NUMBER() OVER(PARTITION BY t2.id ORDER BY t2.create_date) as rn
FROM t2
)
SELECT t1.ID, a.FieldID, a.Field1, a.Field2, a.Field3, a.Field4 FROM A
INNER JOIN T1
ON t1.id = t2.id
WHERE A.RN = 1