我在这个结构中有表:
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
我想通过值列的不同组合(item
或number_value
或string_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 数据库。
答案 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
这是否具有高效性是另一回事;如果你打算采用这种设计,速度显然不在考虑因素列表中。
*不是你具体的;谁首先想出了这个设计。