在一个语句中选择两个表的连接中的第一行
我只需要选择连接表A和B的查询中的第一行。在表B上存在多个具有相同名称的记录。这两个表格中没有任何标识符。我无法改变计划,因为我没有拥有数据库。在一个语句中选择两个表的连接中的第一行
TABLE A
NAME
TABLE B
NAME
DATA1
DATA2
Select Distinct A.NAME,B.DATA1,B.DATA2
From A
Inner Join B on A.NAME = B.NAME
这给了我
NAME DATA1 DATA2
sameName 1 2
sameName 1 3
otherName 5 7
otherName 8 9
,但我需要检索每名只有一排
NAME DATA1 DATA2
sameName 1 2
otherName 5 7
我能够通过添加结果到一个临时表与要做到这一点标识列,然后选择每个名称的最小标识。
这里的问题是,我需要在一个单一的陈述中这样做。
使用GROUP BY可能让你中途有,但要小心。如果你做这样的事情:
Select A.NAME, min(B.DATA1), min(B.DATA2)
From A Inner Join B on A.NAME = B.NAME
Group by A.NAME;
你会得到你正在寻找的结果:
NAME DATA1 DATA2
sameName 1 2
otherName 5 7
但只有您使用测试数据的原因。如果更改数据,从而代替:
otherName 8 9
你有:
otherName 8 4
这将返回:
NAME DATA1 DATA2
sameName 1 2
otherName 5 4
需要注意的是中文别名不从返回DATA1和DATA2相同的记录!
更新:对数据值的一个比较自联接可以帮助你,比如:
SELECT a.*, b.* FROM a,b
LEFT JOIN b b2 ON b.name = b2.name AND b.data2 < b2.data2
WHERE a.name = b.name AND b2.data2 IS NOT NULL;
但是,这只有在DATA2值是每个名称唯一工作。
如果您可以添加到临时表然后从中进行查询,则可以一次完成。
WITH T AS (temp table select), RN AS (select min row-numbers from T) SELECT T.NAME, T.DATA1, T.DATA2 FROM T INNER JOIN RN on T.row_number = RN.row_number
有很多其他的方式来写这个,但这就是我一直在做类似的事情。
尝试重复数据删除b类似这样
SELECT A.NAME, bb.DATA1, bb.DATA2 FROM A JOIN B bb ON A.NAME = B.NAME WHERE NOT EXISTS (SELECT * FROM B WHERE NAME = bb.NAME AND (DATA1 > bb.DATA1 OR DATA1 = bb.DATA1 AND DATA2 > bb.DATA2))
添加更多或条款是否存在更多的数据X列。
如果A也包含重复项,则只需在OP中使用DISTINCT即可。
这将工作:
with temp as (
select A.NAME, B.DATA1, B.DATA2,
row_number() over (partition by A.NAME order by A.NAME) as rownum
from TABLEA A inner join TABLEB B
on A.NAME = B.NAME
)
select NAME, DATA1, DATA2 from temp where rownum = 1
如果你想选择数据1的最低值,并将其数据2中,然后利用这种变化:
with temp as (
select A.NAME, B.DATA1, B.DATA2,
row_number() over (partition by A.NAME order by B.DATA1, B.DATA2) as rownum
from TABLEA A inner join TABLEB B
on A.NAME = B.NAME
)
select NAME, DATA1, DATA2 from temp where rownum = 1
这两个查询会给每一个行名称。
这会给你想要的结果,提供B.DATA1值是与表A
如果他们不是唯一的集内独特,我唯一知道的另一种方式是使用在MSSQL 2005及以上版本中交叉应用。
这个问题的标签表明,这将是DB2的解决方案,但是这是非常相似的MS-SQL服务器,如果是这样尝试以下解决方案:
使用交叉,将有可能显示什么只存在于两个表
select A.*, B.DATA1, B.DATA2
from A
cross apply (select top 1 * from B where B.name = A.name) B
但它有可能改变到OUTER显示在一个什么不存在的义务在乙
select A.*, B.DATA1, B.DATA2
from A
OUTER apply (select top 1 * from B where B.name = A.name) B
存在在structu因为在表B中没有关于退出顺序的指示,所以也可能包含ORDER语句。
您可以使用行号为每个名称获取一行,尝试类似低于
Select name,data1,data2 from
(Select A.NAME,B.DATA1,B.DATA2,row_number() over(partitioj by a.name order by a.name) rn
From A
Inner Join B on A.NAME = B.NAME) where rn=1
上一条语句有小错字。它应该是“IS NOT NULL”而不是“IN NOT NULL”。 – mbp 2010-03-17 20:27:32
+1你是一个救世主。由于SQL CE的限制,即使使用SQL CE,您编辑的自连接也可以工作,因为此问题的其他解决方案并不适用。 – 2012-04-27 06:43:48