需要帮助限制Transact-sql中的连接

时间:2010-04-15 17:19:28

标签: sql tsql join sql-server-2000

我对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 / foobar / bar] MS Access有一个方便的FIRST功能,可以做到这一点,但我没有在TSQL中找到了一个等价物。

此外,如果它有所不同,其他表连接到ACCOUNTS,但这是结构中唯一使用LOGINS。

非常感谢 非常

快速添加信息:USERID / PASSWD组合在整个LOGIN表中都是唯一的。

4 个答案:

答案 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;

(实际上没有尝试运行这些,所以语法错误可能已经在某处悄悄上升)