我对SQL有点新,需要查询语法方面的帮助。
我的问题涉及Transact-SQL(MS SQL Server 2000查询分析器)下更大的多表连接中的2个表
我有ACCOUNTS和LOGINS,它们分别在2个领域加入:Site&子集。 对于每个站点/子集组合,两个表可能都有多行。
ACCOUNTS: | LOGINS: SITE SUBSET FIELD FIELD FIELD | SITE SUBSET USERID PASSWD alpha bravo blah blah blah | alpha bravo foo bar alpha charlie blah blah blah | alpha bravo bar foo alpha charlie bleh bleh blue | alpha charlie id ego delta bravo blah blah blah | delta bravo john welcome delta foxtrot blah blah blah | delta bravo jane welcome | delta bravo ken welcome | delta bravo barbara welcome
我想在ACCOUNTS中选择所有包含LOGIN条目的行,但每个帐户只能 1 登录。
DESIRED RESULT: SITE SUBSET FIELD FIELD FIELD USERID PASSWD alpha bravo blah blah blah foo bar alpha charlie blah blah blah id ego alpha charlie bleh bleh blue id ego delta bravo blah blah blah jane welcome
我真的不在乎我从登录表中找到哪个行,但UserID和Password必须对应。 [不要返回无效的组合,例如foo
/ foo
或bar
/ bar
] MS Access有一个方便的FIRST功能,可以做到这一点,但我没有在TSQL中找到了一个等价物。
此外,如果它有所不同,其他表连接到ACCOUNTS,但这是结构中唯一使用LOGINS。
快速添加信息:USERID / PASSWD组合在整个LOGIN表中都是唯一的。
答案 0 :(得分:1)
使用自动编号字段会更容易。你没有这个表的好主键。
Select *
From
(
Select max(id) as MaxID, Site, Subset
from logins
group by site, subset
) UniqueLogins
INNER JOIN logins on UniqueLogins.MaxID = Logins.ID
INNER JOIN Accounts ON logins.site = accounts.site and logins.subset = accounts.subset
编辑: 如果您无法更改架构,则可以始终将记录转储到具有自动编号的临时表中,但如果经常运行它可能效率低下,但它可以正常工作。
再次编辑: 如果你采用临时表方法,那么代码是:
create table #tmp(
ID int identity(1,1) primary key
,Site <data type>
,Subset <data type>
,userid <data type>
,password <data type>
)
Insert into #tmp(Site
,Subset
,userid
,password )
Select * From logins
--where ???
Select *
From
)
Select #tmp.* From(
Select max(id) as MaxID, Site, Subset
from #tmp
group by site, subset
) UniqueSites
INNER JOIN #tmp on #tmp.ID = UniqueSites.MaxID
) UniqueLogins
INNER JOIN Accounts ON UniqueLogins.Site = Accounts.Site and UniqueLogins.Subset = Accounts.Subset
--do whatever else
drop table #tmp
答案 1 :(得分:1)
我尝试了其中几个答案,但成效有限。
我最终通过连接USERID&amp; amp;来解决了这个问题。 select语句中的PASSWD字段,并使用MAX值只返回一个。
换句话说:
SELECT ac.SITE, ac.SUBSET, MAX('user='lo.USERID+'&password='+lo.PASSWD) as IdPwd FROM ACCOUNTS ac, LOGIN lo WHERE ac.SITE = lo.SITE AND ac.SUBSET = lo.SUBSET GROUP BY ac.SITE, ac.SUBSET
答案 2 :(得分:0)
这是一个可能有效的查询
Select accounts.Site, accounts.Subset, Logins.UserId, Logins.Passwd
From Accounts
Inner Join
(
select top 1 Site, Subset, UserId, Passwd
From Logins logn
Where Exists
(
Select 1
From Accounts Acc
where 1=1
and Acc.Site = Logn.Site
and Acc.Subset = Logn.Subset
)
) as OneLoginPerSite
On Accounts.Site = OneLoginPerSite.Site
and Accounts.Subset = OneLoginPerSite.Subset
内部SELECT只为您提供一个登录帐户,然后您将其加入帐户以获取最终结果。
答案 3 :(得分:0)
这可能会假设USERID / PASSWD组合每个SITE / SUBSET组合是唯一的
select a.*, l1.USERID, l1.PASSWD
from ACCOUNTS a
join LOGINS l1 on a.SITE = l1.SITE and a.SUBSET = l1.SUBSET
where not exists (select * from LOGINS l2 where l1.SITE = l2.SITE and l1.SUBSET = l2.SUBSET and l2.USERID < l1.USERID and l2.PASSWD < l1.PASSWD);
也试试看它是否运行得更快
select a.*, l1.USERID, l1.PASSWD
from ACCOUNTS a
join LOGINS l1 on a.SITE = l1.SITE and a.SUBSET = l1.SUBSET
left outer join LOGINS l2 on l1.SITE = l2.SITE and l1.SUBSET = l2.SUBSET and l2.USERID < l1.USERID and l2.PASSWD < l1.PASSWD
where l2.SITE is null;
(实际上没有尝试运行这些,所以语法错误可能已经在某处悄悄上升)