NOT IN 和 SQL 连接

Posted

技术标签:

【中文标题】NOT IN 和 SQL 连接【英文标题】:NOT IN and a SQL join 【发布时间】:2016-07-11 16:17:12 【问题描述】:

我编写了一个 SQL 语句,其中这些特定列来自一个表,它与另一个表连接,主键 ReportID 用作两个表之间的链接。 I am using NOT IN to accurately display the reports of a company, but I get no output when a company is selected.查询中是否有我必须重新排列的地方?

    valsql1 = "SELECT DISTINCT c.ReportID, c.COMPANYID, rl.REPORTNAME 
                FROM  CompanyReportListTable c 
                right join ReportList rl  on c.reportid = rl.ReportID 
                WHERE c.reportid  NOT IN(Select rl.ReportID FROM ReportList rl) 
                and rl.ReportVisible = 1 
                and CompanyID = " & DropDownList1.SelectedValue

【问题讨论】:

mysql和SQL-Server不是一回事,你实际用的是哪个? 在暴露于 sql 注入之前,您应该阅读、理解并开始使用参数化查询。 您的not in 选择您加入的表中的所有记录,不包括其中的所有记录。 @RonRonmonsterererAnkrah - 它将禁用数据库中的所有约束并删除数据库中的所有表。开始使用参数化查询来避免像上面那样的 sql 注入。 Prdp 试图解释 SQL 注入攻击可能出现的问题。这些都与您提出的问题无关。有很多关于 SQL 注入的信息供您追踪。 【参考方案1】:

我认为您不想排除所有报告。很难猜测这两个不同表格的用途,但我相信您只需要修剪您试图排除的报告列表即可。 (在另一个答案中,您指的是“未经检查的报告或空值”。)

SELECT ReportID, COMPANYID, REPORTNAME 
FROM CompanyReportListTable c
WHERE
    ReportID NOT IN
        (
        SELECT rl.ReportID FROM ReportList rl
        WHERE ... /* which reports are you trying to exclude? */
        ) 
    AND ReportVisible = 1 AND CompanyID = ?

【讨论】:

我能够让复选框出现,并且选中的复选框数量会有所不同,这意味着这些复选框数量适合公司。问题是 ReportName 未显示或无法绑定。【参考方案2】:

NOT IN 不需要它,如果你只是在连接上使用,为什么要使用 in,它没有任何好处,唯一的方法就是你必须选择同一张表的其他记录(当你使用类似树结构的东西),你想要做的是所有的结果都是零记录。

我想你只是想要这样的东西:

valsql1 = "SELECT DISTINCT c.ReportID, c.COMPANYID, rl.REPORTNAME 
   FROM  CompanyReportListTable c 
         right join ReportList rl  on c.reportid = rl.ReportID 
   WHERE rl.ReportVisible = 1 
         and CompanyID = " & DropDownList1.SelectedValue

内部连接看起来像这样:

valsql1 = "SELECT DISTINCT c.ReportID, c.COMPANYID, rl.REPORTNAME 
   FROM  CompanyReportListTable c 
         inner join ReportList rl  on c.reportid = rl.ReportID 
   WHERE rl.ReportVisible = 1 
         and CompanyID = " & DropDownList1.SelectedValue

左连接的最后一个例子:

valsql1 = "SELECT DISTINCT c.ReportID, c.COMPANYID, rl.REPORTNAME 
   FROM  CompanyReportListTable c 
         left join ReportList rl  on c.reportid = rl.ReportID 
   WHERE rl.ReportVisible = 1 
         and CompanyID = " & DropDownList1.SelectedValue

【讨论】:

我做了并且一开始它有效,但是,我意识到它会显示比预期更多的值,所以我的意图是坚持那个加入声明,无论公司如何都显示所有报告,但排除未经检查的报告,或者准确地说是空值。现在,从你所说的零记录来看,我现在正在经历。 如果您不想要空结果,只需使用“内连接”而不是使用“右连接”(如果在另一张表上找不到右连接,则在这种情况下左连接返回 null),现在看看内部连接的答案。 通过使用内部联接,我得到了适合公司的报告。但是现在,假设显示了那些适当的报告,但也显示了其他不适合公司且未检查的报告。我会恢复到右连接还是使用 NOT IN 或 NOT EXIST? Unchecked是什么意思,是不是表示CompanyReportListTable表上没有,还是表示rl.ReportVisible = 0 我相信CompanyReportListTable【参考方案3】:

所以这是我为解决这个问题所做的:删除 DISTINCT 关键字,保留两个表的正确连接。将reportvisible 设置为1。从下拉列表中选择公司后,ReportList 表rl 下的reportID,不是使用NOT IN,而是使用IN,从表2 ReportList 中选择ReportID,并使其保持可见并排序为了清楚起见,它的名字。通过保留它,它将准确显示每个公司的结果,但这次,取消选中每个公司未关联的结果。因此,无论每家公司有多少报告,它都会显示与之相关的报告。这是正确的查询

valsql1 = "SELECT c.ReportID, c.COMPANYID, rl.REPORTNAME 
FROM  CompanyReportListTable c 
right  join  ReportList rl on c.reportid = rl.ReportID and reportvisible = 1 and CompanyID =" & DropDownList1.SelectedValue & " 
where rl.ReportID IN (Select ReportID from ReportList where ReportVisible = 1) 
order by ReportName"

【讨论】:

以上是关于NOT IN 和 SQL 连接的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别