1

我是 SQL 新手,我想实现以下查询:

我有两张桌子,LicenseTbl并且UnlockTbl

LicenseTbl包含有关购买的软件许可证的信息:

LicenseID, ProgramID, Owner, Location, OrderNo, BlockTime

UnlockTbl包含有关特定软件注册的信息:

UnlockID、LicenseID(LicenseTbl 中的外键)、Timestamp、SerialNo、Key、UninstallTime

其中 BlockTime 和 UninstallTime 包含一个时间戳,如果许可证被阻止或软件被卸载等等NULL

我想设计一个查询,为我提供满足以下条件的所有 LicenseID:

  • 属于给定的客户,
  • 没有被封锁,
  • 未在 UnlockTbl 中列出,或者在未标记为已卸载的行中有 < X 个不同的 SerialNo。

我已经写了这个,但我不确定它是否绝对正确(这是我的第一个 SQL 查询之一):

SELECT LicenseID FROM LicenseTbl
JOIN UnlockTbl
   ON (LicenseTbl.LicenseID = UnlockTbl.LicenseID) 
WHERE  LicenseTbl.OrderNo   = '$givenOrderNo'
   AND LicenseTbl.Owner     = '$givenOwner'
   AND LicenseTbl.Location  = '$givenLocation'
   AND LicenseTbl.BlockTime IS NULL
   AND UnlockTbl.UninstallTime IS NULL
GROUP BY LicenseTbl.LicenseID, UnlockTbl.Key
HAVING COUNT(*) < $X

(这应该意味着,列出同时使用少于 X 次的所有许可证。我更喜欢那些首先使用最少但不知道如何排序的许可证。)

4

1 回答 1

4

这是一个好的开始,但我会将查询更改为以下内容......

SELECT
  LicenseID
FROM
  LicenseTbl
LEFT JOIN
  UnlockTbl
    ON  UnlockTbl.LicenseID = LicenseTbl.LicenseID
    AND UnlockTbl.UninstallTime IS NULL
WHERE
      LicenseTbl.OrderNo   = '$givenOrderNo'
  AND LicenseTbl.Owner     = '$givenOwner'
  AND LicenseTbl.Location  = '$givenLocation'
  AND LicenseTbl.BlockTime IS NULL
GROUP BY
  LicenseTbl.LicenseID
HAVING
  COUNT(DISTINCT UnlockTbl.SerialNo) < $X
ORDER BY
  COUNT(DISTINCT UnlockTbl.SerialNo)

1)。LEFT JOIN

ALEFT JOIN确保LicenseTbl返回所有行,即使UnlockTbl表中没有匹配项。 (如果没有匹配项,则UnlockTbl表的值都表示为NULL。)

2)。UnlockTbl.UninstallTime IS NULLJOIN而不是WHERE

WHERE子句应用于. _ JOIN这意味着任何具有实际值(NOT NULL)UnlockTbl的记录都会被加入,然后被过滤掉。这反过来意味着,如果 中的所有相关记录在 中具有非 NULL 值,则该许可证的所有行都将被过滤。UninstallTimeUnlockTblUninstallTime

3)。GROUP BY只是许可证,而不是密钥。

简单地说,我不知道你为什么把它放在那里,而且它没有出现在你想要的英文描述中。

由于您需要 LicenseID 列表,因此按该字段分组可确保您获得每个 LicenseID 一条记录。

4)。HAVING子句修改为查看COUNT(DISTINCT SerialNo)

COUNT(*)计算所有记录。即使没有匹配(所有UnlockTbl值都显示为 NULL),这也会返回1

COUNT(SerialNo)只计算SerialNo不为空的记录。如果没有匹配(所有UnlockTbl值都显示为 NULL),这将返回0

COUNT(DISTINCT SerialNo)也只计算SerialNo不为 NULL 的记录,但将 sme 值的重复项视为仅 1 个条目。

5)。ORDER BY COUNT(DISTINCT SerialNo)

采用与在子句中过滤的值相同的值HAVING,并按其排序。

于 2012-06-08T23:51:53.507 回答