查询"ALL IN"喜欢。 SQL 服务器 2012

Query "ALL IN" like. SQL Server 2012

我在 4 table 之间有这种关系:

还有一个叫做 dataType (dataTypeId, type) 的另一个 table在 LogParamsBookData 值中。

问题如下,all stuff in Books is related to some stuff在 Logs 中,它与额外的 data.

相关

我正在尝试获取将书籍与特定类型的日志条目相关联的查询。想象一下 Log table 存储 什么时候从什么 url 一本书被加载,但是基于它的 "extra data" 而不是它的 Id(我知道这没有意义,但我不能 post 我的真实案例,这是我能想到的更好的例子)。

SELECT 
    b.Id, b.bookName, bd.Id, bd.data, 
    bd.DataTypeId, dt.type
FROM 
    books b
INNER JOIN 
    bookData bd ON b.Id = bd.bookId 
INNER JOIN 
    dataType dt ON bd.dataTypeId= dt.Id
WHERE 
    date > GETDATE() 

此查询的结果与此其他查询的结果相关:

SELECT 
    log.Id, log.logInfo, logParams.logId, logParams.Id, 
    logParams.value, logParams.dataTypeId 
FROM 
    logs
INNER JOIN 
    logParams ON log.Id = logParams.logId 
WHERE 
    logTypeId = 4

这些查询将抛出相同的结果编号。 Log table 值和 Books table 值会不同,但是 logParams 和 bookData 值对于 1 个日志条目和 1 个书籍条目是相同的。

示例:

第一个查询结果

[
   {id: 1, bookName: "Ender's Game", bookDataId: 6, value: "Orson Scott Card", dataTypeId: 6, type: "Author"},
   {id: 1, bookName: "Ender's Game", bookDataId: 7, value: "Amazon", dataTypeId: 8, type: "Seller"},
   {id: 6, bookName: "Ender's Shadow", bookDataId: 9, value: "Orson Scott Card", dataTypeId: 6, type: "Author"},
   {id: 6, bookName: "Ender's Shadow", bookDataId: 15, value: "Book House", dataTypeId: 8, type: "Seller"},
]

第二个:

[
   {"id": "14", "logInfo": "Called from /homePage", "logParamId": "2", "value": "Orson Scott Card", "dataTypeId": "6", "type": "Author",  "logTypeId": "4", "timestamp": "28/02/2015 00:00:00"},
   {"id": "14", "logInfo": "Called from /homePage", "logParamId": "3", "value": "Amazon", "dataTypeId": "8", "type": "Seller", "logTypeId": "4", "timestamp": "28/02/2015 00:00:00"},
   {"id": "65", "logInfo": "Called from /authors", "logParamId": "6", "value": "Orson Scott Card", "dataTypeId": "6", "type": "Author",  "logTypeId": "4", "timestamp": "28/09/2015 00:00:00"},
   {"id": "65", "logInfo": "Called From /authors", "logParamId": "7", "value": "Book House", "dataTypeId": "8", "type": "Seller",  "logTypeId": "4", "timestamp": "28/09/2015 00:00:00"},
   {"id": "16", "logInfo": "Called from /homePage", "logParamId": "11", "value": "Orson Scott Card", "dataTypeId": "6", "type": "Author", "logTypeId": "4", "timestamp": "28/03/2015 00:00:00"},
   {"id": "16", "logInfo": "Called from /homePage", "logParamId": "12", "value": "Amazon", "dataTypeId": "8", "type": "Seller",  "logTypeId": "4", "timestamp": "28/03/2015 00:00:00"},
   {"id": "22", "logInfo": "Called from /homePage", "logParamId": "22", "value": "Orson Scott Card", "dataTypeId": "6", "type": "Author",  "logTypeId": "4", "timestamp": "24/02/2015 00:00:00"},
   {"id": "22", "logInfo": "Called from /homePage", "logParamId": "23", "value": "Amazon", "dataTypeId": "8", "logTypeId": "4","type": "Seller",  "timestamp": "24/02/2015 00:00:00"},
   {"id": "25", "logInfo": "Called from /authors", "logParamId": "32", "value": "Orson Scott Card", "dataTypeId": "6", "type": "Author",  "logTypeId": "4", "timestamp": "21/02/2015 00:00:00"},
   {"id": "25", "logInfo": "Called from /authors", "logParamId": "43", "value": "Book House", "dataTypeId": "8", "logTypeId": "4", "type": "Seller", "timestamp": "21/02/2015 00:00:00"}
]

条目是日志,可以重复使用不同的时间戳,我的意思是,Book1 总是 "Called from HOME" 但它会出现很多次,因为时间戳。

所以我想获取与过滤后的图书查询结果相关的所有日志条目,它必须使用 logParamsbookData "JOIN" 的值。

希望现在更容易理解了。

我想要得到的结果是:

[
  {logId: 14},
  {logId: 65},
  {logId: 16},
  {logId: 22},
  {logId: 25},
 ]

因为它们是 logs,与 books 具有相同的 group 额外数据值 我过滤了第一个查询。

如果 Book 具有类型 6 和 8 的参数且值为 "Scott Card" 和 "Amazon",则相应的日志必须具有相同的值并且 相同的值,不多也不少。

会有多个日志,其参数 "Scott Card" 和 "Amazon" 类型为 6 和 8,只是时间戳不同。

这是一个查询,它连接 tables logParamsbookData 共有的不同列,并且要求每个 logParams 记录某本书在 bookData table:

中有匹配项
SELECT      logParams.LogId
FROM        logParams
INNER JOIN  logs
        ON  logs.logTypeId = 4
        AND logs.Id = logParams.logId 
LEFT JOIN   bookData
        ON  bookData.dataTypeId = logParams.dataTypeId
        AND bookData.data = logParams.data
LEFT JOIN   books 
        ON  books.Id = bookData.bookId
        AND books.date > GETDATE() 
GROUP BY    logParams.LogId
HAVING      COUNT(DISTINCT logParams.dataTypeId) 
          = COUNT(DISTINCT bookData.dataTypeId)

HAVING 子句强制执行您所谓的 "ALL IN" 条件,即它确保每个 LogId 的所有 logParams 记录都与来自 bookData。如果有 logParams 条记录不匹配,则排除相应的 Logs 条目。

这是一个 fiddle,它根据问题中提供的数据输出这些记录:

LogId
-----
14
16
22
25
65