选择那些既在数组中又不在表格中的数字

5

我在 MySql 中有一张表,里面存储了一些数据,比如一个名字和一个排名。

我知道排名是从1到100的,我想选择那些没有被占用的排名。例如,假设我们只有5个排名,以及以下表格:

|  name  |  stand  |
--------------------
|  test  |    1    |
|  anot  |    3    |
|  blah  |    4    |
|  uuuh  |    5    |

在这种情况下,唯一的免费立场将是“2”。是否有一个语句可以实现这个目的?我在想使用“NOT IN”子句,但我无法想出代码...也许如果我能在MySql中定义一个数组呢?

1
如果你知道怎么把所有的 stand 放入一个数组中,那么你就可以使用类似 $freeStands = array_diff(range(1,100), $idArray)); 这样的代码。 - Jon
哦...在 SQL 外面...我没有考虑到,谢谢,这应该是一个解决方案。 - Matteo Bononi 'peorthyr'
1
@Akam 只有当表中存在具有“stands”列可用但为空(或未在定义的列表中)的行时,才能起作用。但是,如果数据一开始就不在数据库中,这也无济于事。 - Jon
2
你可以在mysql中定义一个数组,它被称为表。 - palindrom
1
你显然是正确的,但我无法访问数据库结构,太简单了:D 顺便说一下,是的,这是正确的方法,在这种特殊情况下,正确的方法是像Jon在开头所说的那样离开mysql。 - Matteo Bononi 'peorthyr'
显示剩余2条评论
3个回答

2

如果你知道数值从1到100,那么你可以这样做:

select n.num
from (select d1.d*10 + d2.d as n
      from (select 0 as d union all select 1 union all select 2 union all select 3 union all select 4 union all
            select 5 union all select 6 union all select 7 union all select 8 union all select 9
           ) d1 cross join
           (select 0 as d union all select 1 union all select 2 union all select 3 union all select 4 union all
            select 5 union all select 6 union all select 7 union all select 8 union all select 9
           ) d2
      ) nums left outer join
      stands s
      on s.stand = nums.n cross join
      (select min(stand) as minstand and max(stand) as maxstand from stands) const
where s.stand is null and nums.n between minstand and maxstand;

这段代码未经测试,可能存在语法错误。

即创建一个包含所有可能值(1到100)的表格。将其与你的表格进行左连接,这将提供你所有未使用的数字。然而,你需要限制它在最小和最大值之间,因此计算这些值并用于过滤。


1
你可以使用整数表来获取数字范围。
例如:
SELECT a.i + b.i * 10 + c.i * 100 FROM integers a, integers b, integers c

有一个名为整数的表,只有一列名为i,其中有10行,值为0到9,这将给您所有0到999之间的数字(您可以轻松地再次加入表格以获取更大的数字)。

您可以将其与您的表连接以查找未使用的数字:

SELECT *
FROM (SELECT a.i + b.i * 10 + c.i * 100 AS anInt FROM integers a, integers b, integers c) Sub1
LEFT OUTER JOIN someTable
ON Sub1.anInt = someTable.stand
WHERE someTable.stand IS NULL

这样做可以实现,但是会在范围两端返回所有数字。如果需要这些数字,您需要将它们与最小值和最大值连接起来。
SELECT Sub1.anInt
FROM (SELECT a.i + b.i * 10 + c.i * 100 AS anInt FROM integers a, integers b, integers c) Sub1
INNER JOIN (SELECT MIN(stand) AS MinStand, MAX(stand) AS MaxStand FROM someTable) Sub2
ON Sub1.anInt >= Sub2.MinStand AND Sub1.anInt <= Sub2.MaxStand
LEFT OUTER JOIN someTable
ON Sub1.anInt = someTable.stand
WHERE someTable.stand IS NULL

1

在我看来,一个更简单的解决方案是创建一张包含从1到100所有数字的表。然后对该表进行左连接,并展示任何不匹配的值。

您可以创建一张名为"integer_values"的表,其中包含一个名为"value"的字段。然后将其填充为从1到100的所有数字。接下来,您可以使用以下查询:

SELECT  i.value

FROM    integer_values AS i

        LEFT JOIN stands AS s
        ON i.value = s.stand

WHERE   s.stand IS NULL

这可能是正确的方法,但我无法访问数据库结构,因此无法更改任何表:/ - Matteo Bononi 'peorthyr'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接