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

发布于 2024-08-28 16:06:47 字数 1064 浏览 2 评论 0原文

我对 SQL 有点陌生,需要查询语法方面的帮助。

我的问题涉及 Transact-SQL(MS SQL Server 2000 查询分析器)下较大的多表联接中的 2 个表,

我有 ACCOUNTS 和 LOGINS,它们在 2 个字段上联接:站点和帐户。子集。 对于每个站点/子集组合,两个表都可以有多个行。

帐户: |登录:
  站点子集 字段 字段 |站点子集 用户 ID 密码
  阿尔法布拉沃等等等等|阿尔法·布拉沃·富酒吧
  阿尔法查理等等等等 |阿尔法布拉沃酒吧富
  阿尔法查理布莱布莱布莱|阿尔法查理布莱布莱布莱|阿尔法查理的自我
  三角洲布拉沃等等等等|三角洲布拉沃约翰欢迎
  三角洲狐步舞等等等等|三角洲布拉沃简欢迎
                                          |三角洲布拉沃肯欢迎
                                          | delta bravo barbara 欢迎

我想选择帐户中具有登录条目的所有行,但每个帐户仅 1 登录。

所需结果:
  站点子集字段字段字段用户 ID 密码
  alpha bravo 等等等等 foo 酒吧
  阿尔法查理等等等等我的自我
  阿尔法查理布莱布莱布莱蓝色身份自我
  delta bravo blah blah blah jane 欢迎

我并不关心登录表中的哪一行,但用户 ID 和密码必须对应。 [不要返回无效的组合,如 foo/foobar/bar] MS Access 有一个方便的 FIRST函数,它可以做到这一点,但我还没有在 TSQL 中找到等效的函数。

另外,如果有区别的话,其他表也会连接到 ACCOUNTS,但这是结构中 LOGINS 的唯一用途。

非常感谢您非常的帮助。

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

I'm somewhat new to SQL and need help with query syntax.

My issue involves 2 tables within a larger multi-table join under Transact-SQL (MS SQL Server 2000 Query Analyzer)

I have ACCOUNTS and LOGINS, which are joined on 2 fields: Site & Subset.
Both tables may have multiple rows for each Site/Subset combination.

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

I want to select all rows in ACCOUNTS which have LOGIN entries, but only 1 login per account.

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

I don't really care which row from the login table I get, but the UserID and Password have to correspond. [Don't return invalid combinations like foo/foo or bar/bar] MS Access has a handy FIRST function, which can do this, but I haven't found an equivalent in TSQL.

Also, if it makes a difference, other tables are joined to ACCOUNTS, but this is the only use of LOGINS in the structure.

Thank you very much for any assistance.

Quick added info: USERID/PASSWD combinations are unique across the entire LOGIN table.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

话少心凉 2024-09-04 16:06:47

我尝试了其中的几个答案,但成功程度有限。

我最终通过连接 USERID 和 USERID 解决了这个问题。 select 语句中的 PASSWD 字段并使用 MAX 值时仅返回 1。

换句话说:

SELECT ac.SITE, ac.SUBSET, MAX('user='lo.USERID+'&password='+lo.PASSWD) as IdPwd
从帐户 ac,登录 lo
其中 ac.SITE = lo.SITE
AND ac.SUBSET = lo.SUBSET
按 ac.SITE、ac.SUBSET 分组

I tried several of these answers, with limited degrees of success.

I eventually solved the issue by concatenating the USERID & PASSWD fields in the select statement and used the MAX value to return only one.

In other words:

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
深海里的那抹蓝 2024-09-04 16:06:47

使用自动编号字段会更容易。您实际上没有该表的良好主键。

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

It would be easier with an autonumber field. You don't really have a good primary key for this table.

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

Edit:
If you can't change schema, you can always dump the records into a temp table with an autonumber, but it may be inefficient if this is being run often, but it will work.

Edit again:
If you went the temp table approach, the code for that is:

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
伏妖词 2024-09-04 16:06:47

这是一个可能有效的查询,

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 只为每个帐户提供一次登录,然后将其连接回帐户以获得最终结果。

Here is a query that may work

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

The Inner SELECT gets you only one Login per Account and then you join this back to the Accounts to get your final result.

梦幻之岛 2024-09-04 16:06:47

假设 USERID/PASSWD 组合对于每个站点/子集组合都是唯一的,这可能会起作用,

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;

(实际上并没有尝试运行这些,因此语法错误可能已经出现在某个地方)

This may work assuming that USERID/PASSWD combos are unique per SITE/SUBSET combo

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);

also try this to see if it runs faster

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;

(didn't actually try running these, so a syntax error may have crept in somewhere)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文