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_value
或 string_value/number_value
或 string_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
这是否具有性能是另一回事;如果您*打算采用这种设计,那么速度显然不是考虑因素的重中之重。
*不是你特指;谁最先想到这个设计。
我在这个结构中有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_value
或 string_value/number_value
或 string_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
这是否具有性能是另一回事;如果您*打算采用这种设计,那么速度显然不是考虑因素的重中之重。
*不是你特指;谁最先想到这个设计。