【问题标题】:Multiple Inner Join needed to check If rows exist? - SQL Server需要多个内部联接来检查行是否存在? - SQL 服务器
【发布时间】:2020-04-29 10:52:49
【问题描述】:

我已经重新提交了这个问题,因为它有错误,我相信我现在已经修复了,抱歉。

好的,以下存储过程可以正常工作,但我需要添加另一个与另一个名为 tblItems 的表相关的条件。我要求tblAccounts.accountID 加入tblItems.AccountID,这样我可以检查tblItems.fileID > 0 是否是,如果是,则返回结果。这是我的表格和预期结果..

TBLACCOUNTS: AccountID, ContactName, SkypeUserName, friendlyOrderID

TBLORDERS: AccountID, ItemsAllowed

TBLITEMS: AccountID, FileID, ImageUrl

我希望实现的是这个..

4B900A74-E2D9-4837-B9A4-9E828752716E  PETER     PETE  827365
E82882D9-4837-B9A4-9E82-22228752716E  MATTHEW   MATT  373926
4B900A74-2323-1414-2525235252533333D  JONATHAN  JON   732792...

下面的第一个代码块是做什么的。 但我只需要每个用户在 tblItems 中至少有 1 个 fileID 的行。当我尝试下面的第二个代码块时得到的结果如下..

4B900A74-E2D9-4837-B9A4-9E828752716E  PETER     PETE  827365
4B900A74-E2D9-4837-B9A4-9E828752716E  PETER     PETE  827365
4B900A74-E2D9-4837-B9A4-9E828752716E  PETER     PETE  827365...

代码块1

SELECT 
    *,
    CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
FROM
    (SELECT 
         ROW_NUMBER() OVER (ORDER BY dateAdded DESC) AS [RowNo],
         COUNT(*) OVER () cnt,
         tblAccounts.skypeUserName, tblAccounts.contactName, 
         tblorders.friendlyOrderID
     FROM 
         tblOrders
     INNER JOIN 
         tblAccounts ON tblOrders.accountID = tblAccounts.accountID
     WHERE 
         bootSaleDate = @bootSaleDate AND orderStatus = 'Completed') t
WHERE 
    RowNo BETWEEN (@page * 8) - 7 AND (@page * 8)

这是我尝试过的 (Codeblock2)..

SELECT *,
CASE WHEN RowNo < cnt THEN 'N' ELSE 'Y' END AS lastbox
    FROM
    (
    SELECT ROW_NUMBER() OVER (ORDER BY orderDate desc) as [RowNo],
    COUNT(*) OVER () cnt,
    tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
    FROM tblOrders
    INNER JOIN tblAccounts ON tblOrders.accountID=tblAccounts.accountID
    INNER JOIN tblItems ON tblOrders.accountID=tblItems.accountID
    WHERE EXISTS(select 1 from tblItems WHERE tblItems.fileID > 0 AND tblItems.accountID = 
    tblOrders.accountID AND tblOrders.bootSaleDate = @bootSaleDate)  AND tblOrders.bootSaleDate = 
    @bootSaleDate AND tblOrders.orderStatus='Completed' 
    ) t
WHERE RowNo BETWEEN (@page*8)-7 AND (@page*8)

【问题讨论】:

  • 存在检查似乎毫无意义 - 如果基于连接条件存在记录并且连接是累积的,则内部连接只会查找数据,因此即使 from 和第一个内部连接找到它们也会如果最后一个连接没有,则丢弃。也许您只需要 WHERE tblItems.fileID > 0 。样本数据和预期结果会有所帮助。
  • @P.Salmon 我已经更新了原始问题,试图让它更清楚我需要什么。非常感谢您的帮助。
  • 不太清楚,特别是因为您要实现的目标不包含所选项目并且没有标题。退一步说,tblaccounts 中的 account 只有 1 行吗?许多人在 tblorders 中拥有一个帐户?和许多在 tblitems 中的帐户。此外,“在 tblItems 中至少有 1 个文件 ID”是不明确的,它可能意味着每个帐户有 1 行,但文件 ID 的值可以是 0-n,或者一个帐户可能有很多行。
  • @P.Salmon 是的 tblItems 可以有 0,1,2,3,4,5 等行数。我希望为每个用户检索 tblAccounts.skypeUserName、tblAccounts.contactName、tblorders.friendlyOrderID,前提是该用户和该日期的 tblItems 中存在一行。是的,tblorders 和 tblitems 可能包含不止一次出现的相同 accountID。那有意义吗?很抱歉没有完全理解,我还在学习。

标签: sql-server aql


【解决方案1】:

也许您的意思是这样的,其中子查询 s 计算出 fileid > 0 的 tblitems 存在多少行

 drop table tblorders
 drop table tblaccounts
 drop table tblitems
 go

 create table tblorders (accountid int,orderdate smalldatetime,friendlyorderid int,
                bootsaledate smalldatetime, orderstatus varchar(10))
 create table tblaccounts(accountid int,skypeusername varchar(3),contactname varchar(3))
 create table tblitems(accountid int,fileid int)
 insert into tblorders values
 (1,'2020-04-29',1,'2020-04-29','completed'),
 (2,'2020-04-29',1,'2020-04-29','completed')

 insert into tblaccounts values
 (1,'aaa','aaa'),
 (2,'bbb','bbb')

 truncate table tblitems
 insert into tblitems values
 (1,0),(2,2),(1,1)
 declare @bootsaledate smalldatetime
 set @bootsaledate = '2020-04-29'
 SELECT tblorders.accountid,tblaccounts.accountid,s.accountid,
        ROW_NUMBER() OVER (ORDER BY orderDate desc) as [RowNo],
    COUNT(*) OVER () cnt,
    tblAccounts.skypeUserName, tblAccounts.contactName, tblorders.friendlyOrderID
    FROM tblOrders
    INNER JOIN tblAccounts ON tblOrders.accountID=tblAccounts.accountID
    INNER JOIN 
        (select accountid,sum(case when fileid > 0 then 1 else 0 end) fileid 
        from tblitems
        group by accountid) s  ON tblOrders.accountID=s.accountID
    WHERE s.fileID > 0 
    AND tblOrders.bootSaleDate = @bootSaleDate 
    AND tblOrders.orderStatus='Completed' ;

 accountid   accountid   accountid   RowNo                cnt         skypeUserName contactName friendlyOrderID
----------- ----------- ----------- -------------------- ----------- ------------- ----------- ---------------
1           1           1           1                    2           aaa           aaa         1
2           2           2           2                    2           bbb           bbb         1

【讨论】:

  • 这对负载很有帮助,谢谢。这不是我想要的,但我选择了你的代码解决方案的一些部分,这有助于我创建一个解决方案。我主要是缺少 GROUP BY,这就是我得到多个结果的原因。这是一个难以解释的问题,所以感谢您的坚持。
  • 如果有问题没有答案,这对本网站上的其他人没有帮助 - 您可以发布自己的解决方案或删除问题。
猜你喜欢
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多