mysql - 通过检查两列获取出现在一个表中但不在另一个表中的唯一行

标签 mysql sql sqlite

我有三个表:
文件、模块和函数。

我有来自文件 mssip32.dll 的函数和来自文件 ncsi.dll 的函数。

我想获取出现在 mssip32.dll 中但在 nsci.dll 中的所有函数

重要提示:
如果函数的名称或模块不同,则函数也不同。

例如:

ModuleA.CreateProcess != ModuleB.CreateProcess (because they have different module)  

ModuleA.CreateProcess != ModuleA.Sleep         (because have different function name)  

ModuleA.CreateProcess == ModuleA.CreateProcess (equals)  

mssip32.dll 和 nsci.dll 中的函数作为 View :

enter image description here

所有表格:
enter image description here

这是我尝试做的:

SELECT fu.function_name AS 'Imported Function', m.module_name AS 'Library', COUNT(fu.function_name) AS 'Usage Count'
                                FROM File as f,
                                     Module as m,
                                     Function as fu
                                WHERE f.listview_name like 'listView1'
                                AND f.file_id = m.file_id
                                AND f.file_id = fu.file_id
                                AND m.module_id = fu.module_id
                                AND fu.function_name NOT in (
                                                    SELECT fu2.function_name
                                                    FROM File as f2,
                                                         Module as m2,
                                                         Function as fu2
                                                    WHERE f2.listview_name like 'listView2'
                                                    AND f2.file_id = m2.file_id
                                                    AND f2.file_id = fu2.file_id
                                                    AND m2.module_id = fu2.module_id
                                                    )
                                GROUP BY fu.function_name
                                ORDER BY COUNT(fu.function_name) DESC

但是这个的问题是,它没有检查模块名称是否不同,结果是不正确:
enter image description here

我们缺少 ModuleA.CreateProcess,因为它没有出现在“listView2”中。

我希望能够尝试这样的事情(理论上):

...
AND (fu.function_name AND m.module_name) NOT in (
                    SELECT fu2.function_name, m2.module_name
                    FROM File as f2,
                         Module as m2,
                         Function as fu2
                    WHERE f2.listview_name like 'listView2'
                    AND f2.file_id = m2.file_id
                    AND f2.file_id = fu2.file_id
                    AND m2.module_id = fu2.module_id
                    )
...

所以如果我有:

fu.function_name = "CreateProcess"  
m.module_name    = "ModuleA"  

fu2.function_name = "CreateProcess"  
m2.module_name    = "ModuleB"  

它将返回 ((fu.function_name != fu2.function_name) OR (m.module_name != m2.module_name))

然后期望的结果将是:
enter image description here

代码:
表结构:

CREATE TABLE File (
    file_id INTEGER NOT NULL ,
    name VARCHAR(160) NOT NULL ,
    listview_name VARCHAR(30) NOT NULL ,
    type VARCHAR(10) NOT NULL ,
    recursive VARCHAR(10) NOT NULL ,
    PRIMARY KEY (file_id)
) ;

CREATE TABLE Module (
    file_id INTEGER NOT NULL ,
    module_id INTEGER NOT NULL ,
    module_name VARCHAR(30) NOT NULL ,
    PRIMARY KEY (file_id)
) ;

CREATE TABLE Function (
    file_id INTEGER NOT NULL ,
    module_id INTEGER NOT NULL ,
    function_name VARCHAR(30) NOT NULL ,
    PRIMARY KEY (file_id)
) ;

View 结构:

CREATE VIEW function_List1 AS
    SELECT fu.function_name, m.module_name
    FROM File as f,
         Module as m,
         Function as fu
    WHERE f.listview_name like 'listView1'
    AND f.file_id = m.file_id
    AND f.file_id = fu.file_id
    AND m.module_id = fu.module_id

CREATE VIEW function_List2 AS
    SELECT fu2.function_name, m2.module_name
    FROM File as f2,
         Module as m2,
         Function as fu2
         WHERE f2.listview_name like 'listView2'
         AND f2.file_id = m2.file_id
         AND f2.file_id = fu2.file_id
         AND m2.module_id = fu2.module_id

编辑:
我找到了另一种解决方法。
我可以查询 listview2 以获取与 listview1 中的函数具有相同模块的所有函数,然后检查 listview1 中的函数是否在该列表中。
我通过添加 AND m.module_name = m2.module_name 来做到这一点:

AND fu.function_name NOT in (
SELECT fu2.function_name
FROM File as f2,
     Module as m2,
     Function as fu2
WHERE f2.listview_name like 'listView2'
AND f2.file_id = m2.file_id
AND f2.file_id = fu2.file_id
AND m2.module_id = fu2.module_id
AND m.module_name = m2.module_name)

最佳答案

如果您将 and 替换为 ,,您的条件将有效

AND (fu.function_name, m.module_name) NOT in (
                    SELECT fu2.function_name, m2.module_name
                    FROM File as f2,
                         Module as m2,
                         Function as fu2
                    WHERE f2.listview_name like 'listView2'
                    AND f2.file_id = m2.file_id
                    AND f2.file_id = fu2.file_id
                    AND m2.module_id = fu2.module_id
                    )

您可以更改为:

WHERE NOT EXISTS 
      ( SELECT 1
        FROM File as f2,
                             Module as m2,
                             Function as fu2
                        WHERE f2.listview_name like 'listView2'
                        AND f2.file_id = m2.file_id
                        AND f2.file_id = fu2.file_id
                        AND m2.module_id = fu2.module_id
                        AND fu2.function_name = fu.function_name
                        AND m.module_name = m2.module_name
      ) ;

关于mysql - 通过检查两列获取出现在一个表中但不在另一个表中的唯一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40473346/

相关文章:

mysql - 从数据库中获取最小值并在 MySQL 中随机化顺序

mysql - 如何将 JasperReports 5.6 Equal Clause 函数设置为 IS NOT NULL

mysql - 查询以显示所有数据,除非与用户相关

mysql - 如何创建一个 MySQL 查询来获取每月每个日期(如日历)的销售额?

android - 多个 SQLiteOpenHelper 仅在 Android 上创建第一个表

php - mysqli数组到子查询中的mysql?

php - 自动为列中的重复值分配相同的 ID

php db 查询显示某些用户数据(包括 Smarty)

xcode - 将 SQLite3 数据库逆向工程到 coredata

android - 显示数据库中数据的最佳方式