1

我有以下设置:

  • 带有a, b,列的表c
  • 具有随机数项(i1、i2、i3、... in)的数组。
  • 表包含类似的行

    1      1    i1
    1      1    i2
    .      .    .
    .      .    .
    .      .    .
    1      1    in
    1      2    i1
    .      .    .
    .      .    .
    .      .    .
    2      1    i1
    2      2    i2
    

问题是并非所有记录都在那里。例如,第 1 行 2 i1 可能会丢失。

我想做的,从查询(不获取所有行并遍历它们)是查看是否缺少任何行(我不在乎女巫一个,只有一个如果丢失)。

对于更复杂的问题,这是一个非常简化的示例,因此如果我没有清楚地说明它,或者我忘记提及任何内容,请随时询问详细信息。

PHP 中的选择和处理是可以接受的,只要我不选择表中的所有内容(尽管我不知道如何通过处理数据而不选择所有内容来做到这一点,但觉得值得一提)。

你们中的一些人要求一个模式,所以......:

让我们再简化一些......假设第一列有一个可以在那里找到的可能数据数组,对于第 2 列也是如此,对于第 3 列已经说过了。然后应该在表中找到这 3 个之间的所有可能组合. 我需要知道是否缺少任何东西...

4

5 回答 5

1

假设您知道他对列 a 和 b 的值,您可以尝试以下操作:

select c, count (*) group by c;

这将告诉您每个值有多少条目。

i1  3
i2  0
in  3

然后你可以遍历该结果以查看缺少的内容

于 2013-05-30T11:32:40.523 回答
1

假设我们有一个包含这些数据的表。

mysql> SELECT * FROM stuff;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    1 |    1 | i1   |
|    1 |    1 | i2   |
|    1 |    2 | i2   |
|    1 |    2 | i3   |
|    2 |    1 | i1   |
+------+------+------+
5 rows in set (0.00 sec)

我们还假设 C 的所有可能值都在表中。然后我们可以像这样构造一个引用表。

mysql> SELECT a,b,c FROM (SELECT DISTINCT a,b FROM stuff) t1 CROSS JOIN (SELECT DISTINCT c FROM stuff) t2;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    1 |    1 | i1   |
|    1 |    2 | i1   |
|    2 |    1 | i1   |
|    1 |    1 | i2   |
|    1 |    2 | i2   |
|    2 |    1 | i2   |
|    1 |    1 | i3   |
|    1 |    2 | i3   |
|    2 |    1 | i3   |
+------+------+------+
9 rows in set (0.00 sec)

然后,我们可以将表与实际数据和参考表进行比较,方法是将它们像这样连接在一起,并像这样获取所有缺失的行:

mysql> SELECT * FROM stuff RIGHT JOIN (SELECT a,b,c FROM (SELECT DISTINCT a,b FROM stuff) t1 CROSS JOIN (SELECT DISTINCT c FROM stuff) t2) r ON stuff.a = r.a AND stuff.b = r.b AND stuff.c = r.c WHERE stuff.a IS NULL;
+------+------+------+------+------+------+
| a    | b    | c    | a    | b    | c    |
+------+------+------+------+------+------+
| NULL | NULL | NULL |    1 |    2 | i1   |
| NULL | NULL | NULL |    2 |    1 | i2   |
| NULL | NULL | NULL |    1 |    1 | i3   |
| NULL | NULL | NULL |    2 |    1 | i3   |
+------+------+------+------+------+------+
4 rows in set (0.00 sec)

a,b,c 上的 RIGHT JOIN 会将引用表 r 中的行与实际行进行匹配。缺失的行将在内容方面显示为 NULL。因此,我们可以通过在 stuff 表中选择任何具有 NULL 字段的行来获取所有丢失的行。

编辑:您可以SELECT * ...将最后一个查询中的 更改为SELECT count(*) ...并在这种情况下获得缺失行数 4。

于 2013-05-30T11:48:33.143 回答
1

您可以通过简单的计数来做到这一点。预期行数是 A 中不同元素的数量乘以 B 中不同元素的数量乘以 C 中不同元素的数量。

要计算丢失的数字,只需对适当的值进行算术运算:

select (cnt - cntA*cntB*cntC) as NumMissingRows
from (select count(distinct a) as cntA,
             count(distinct b) as cntB,
             count(distinct c) as cntC,
             count(*) as cnt
      from t
     ) t
于 2013-05-30T13:14:51.213 回答
0

这样的查询怎么样,这可能不是最好的性能,但对于一次性任务来说,这应该可以工作。

SELECT t1.id,
(
  SELECT t2.id FROM table t2 WHERE t2.id < t1.id ORDER BY t2.id DESC LIMIT 1
) as prv
FROM table t1
HAVING id <> prv + 1
于 2013-05-30T11:30:22.387 回答
0

我会考虑这样做,即使您的值列表中有重复项,它仍然可以工作。这与对结果字段进行任何循环一样(仅返回一行,它将告诉您在表中未找到数组中的唯一值。

SELECT COUNT(*)
FROM (SELECT 'i1' AS aCol
UNION
SELECT 'i2' AS aCol
UNION
SELECT 'i3' AS aCol
UNION
.......
UNION
SELECT 'in' AS aCol) Sub1
LEFT OUTER JOIN aTable
ON  Sub1.aCol = aTable.c
WHERE aTable.c IS NULL

如果将来需要,也可以很容易地修改以带回未找到的项目列表。

于 2013-05-30T13:48:00.500 回答