Oracle 在按另一列分组的多列中搜索

Oracle search in multiple columns grouped by another column

我在这个结构中有table:

id | item | type | string_value | number_value | date_value 
-----------------------------------------------------------
1  | 11   | S    | abcd         | null         | null
2  | 11   | N    | null         | 134.56       | null
3  | 11   | D    | null         | null         | 2017/01/01
4  | 12   | N    | null         | 134.56       | null
5  | 13   | S    | efgh         | null         | null
6  | 13   | N    | null         | 99           | null
7  | 13   | D    | null         | null         | 2000/05/21
8  | 14   | N    | null         | 5            | null
9  | 14   | D    | null         | null         | 2017/01/01
10 | 15   | S    | cd           | null         | null
11 | 15   | N    | null         | 134.56       | null
12 | 15   | D    | null         | null         | 1998/11/01
13 | 11   | S    | aaacddff     | null         | null
14 | 11   | S    | xxxx         | null         | null

我想通过值列的不同组合(number_valuestring_value/number_valuestring_value/date_value)搜索 item

例如:select distinct item where string_value like '%cd%' and number_value = 134.56。预期结果是 11 和 15(12 适用于 number_value 但没有 string_value

为简单起见,我省略了更多值列。 Table 包含连接 item table 的 ±1 亿行(±200 万行)。主键是 id,对于一个 item,同一个 type 可以有多个值。如果 item 对同一个 type 有多个值,那么每一行是否符合条件并不重要,但至少有一个必须(比如 item 11 在 [abcd, aaacddff 中有 string_value , xxxx] - 前两个符合上述类似条件)。这也涉及到分页。

查询速度在这里至关重要。 Oracle10g数据库

您可以在查询本身中进行合并和检查:

WITH your_table AS (SELECT 1 ID, 11 item, 'S' TYPE, 'abcd' string_value, NULL number_value, NULL date_value FROM dual UNION ALL
                    SELECT 2 ID, 11 item, 'N' TYPE, NULL string_value, 134.56 number_value, NULL date_value FROM dual UNION ALL
                    SELECT 3 ID, 11 item, 'D' TYPE, NULL string_value, NULL number_value, to_date('01/01/2017', 'dd/mm/yyyy') date_value FROM dual UNION ALL
                    SELECT 4 ID, 12 item, 'N' TYPE, NULL string_value, 134.56 number_value, NULL date_value FROM dual UNION ALL
                    SELECT 5 ID, 13 item, 'S' TYPE, 'efgh' string_value, NULL number_value, NULL date_value FROM dual UNION ALL
                    SELECT 6 ID, 13 item, 'N' TYPE, NULL string_value, 99 number_value, NULL date_value FROM dual UNION ALL
                    SELECT 7 ID, 13 item, 'D' TYPE, NULL string_value, NULL number_value, to_date('21/05/2000', 'dd/mm/yyyy') date_value FROM dual UNION ALL
                    SELECT 8 ID, 14 item, 'N' TYPE, NULL string_value, 5 number_value, NULL date_value FROM dual UNION ALL
                    SELECT 9 ID, 14 item, 'D' TYPE, NULL string_value, NULL number_value, to_date('01/01/2017', 'dd/mm/yyyy') date_value FROM dual UNION ALL
                    SELECT 10 ID, 15 item, 'S' TYPE, 'cd' string_value, NULL number_value, NULL date_value FROM dual UNION ALL
                    SELECT 11 ID, 15 item, 'N' TYPE, NULL string_value, 134.56 number_value, NULL date_value FROM dual UNION ALL
                    SELECT 12 ID, 15 item, 'D' TYPE, NULL string_value, NULL number_value, to_date('01/11/1998', 'dd/mm/yyyy') date_value FROM dual UNION ALL
                    SELECT 13 ID, 11 item, 'S' TYPE, 'aaacddff' string_value, NULL number_value, NULL date_value FROM dual UNION ALL
                    SELECT 14 ID, 11 item, 'S' TYPE, 'xxxx' string_value, NULL number_value, NULL date_value FROM dual)
SELECT item
FROM   your_table
WHERE  string_value like '%cd%'
OR     number_value = 134.56
GROUP BY item
HAVING MAX(CASE WHEN string_value like '%cd%' THEN string_value END) IS NOT NULL
       AND MAX(CASE WHEN number_value = 134.56 THEN number_value END) IS NOT NULL;

      ITEM
----------
        11
        15

这是否具有性能是另一回事;如果您*打算采用这种设计,那么速度显然不是考虑因素的重中之重。

*不是你特指;谁最先想到这个设计。