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

时间:2018-04-13 07:37:35

标签: sql oracle oracle10g

我在这个结构中有表:

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

我想通过值列的不同组合(itemnumber_valuestring_value/number_value)搜索string_value/date_value

例如:选择不同的item,其中string_value喜欢'%cd%' number_value = 134.56。预期结果为11和15(12适用于number_value,但没有string_value

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

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

1 个答案:

答案 0 :(得分:0)

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

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

这是否具有高效性是另一回事;如果你打算采用这种设计,速度显然不在考虑因素列表中。

*不是你具体的;谁首先想出了这个设计。