对每个条件的数据重新删除。
在2018年的第一个月中,每周(第一,第二,第三和第4周)将数据分解。
根据以下事实过滤女性的数据,即出生人数的第二和第三位数大于或等于51。
SELECT
disability_name,
SUM(CASE WHEN TO_CHAR(start_date, 'IW') = '01' THEN 1 ELSE 0 END) AS first_week,
SUM(CASE WHEN TO_CHAR(start_date, 'IW') = '02' THEN 1 ELSE 0 END) AS second_week,
SUM(CASE WHEN TO_CHAR(start_date, 'IW') = '03' THEN 1 ELSE 0 END) AS third_week,
SUM(CASE WHEN TO_CHAR(start_date, 'IW') = '04' THEN 1 ELSE 0 END) AS fourth_week
FROM p_disabilities
JOIN p_disability_type
ON p_disabilities.id_disability = p_disability_type.disability_id
WHERE TO_CHAR(start_date, 'YYYY') = '2018'
AND TO_CHAR(start_date, 'MM') = '01'
AND TO_NUMBER(SUBSTR(birth_number, 3, 2)) >= 51
GROUP BY disability_name;
我正在尝试简化此SQL查询,以提高其效率。具体来说,我想提高查询的性能,因为它正在使用潜在的大型数据集。我可以简化或优化此查询的一些方法?
start_date
,Birth_number和
disability_id
中,以确保此查询尽可能快地运行? 表格的标题:
CREATE TABLE p_disabilities (
id_disability CHAR(6) NOT NULL PRIMARY KEY,
birth_number CHAR(11) NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
disability_id NUMBER NOT NULL );
CREATE TABLE p_disability_type (
disability_id NUMBER NOT NULL,
disability_name VARCHAR2(50) );
try以免在WHERE
SUBSTR
。 (但是第二/第三位应该是SUBSTR(birth_number, 2, 2)
SELECT
dt.disability_name,
SUM(CASE WHEN TO_CHAR(d.start_date, 'IW') = '01' THEN 1 ELSE 0 END) AS first_week,
SUM(CASE WHEN TO_CHAR(d.start_date, 'IW') = '02' THEN 1 ELSE 0 END) AS second_week,
SUM(CASE WHEN TO_CHAR(d.start_date, 'IW') = '03' THEN 1 ELSE 0 END) AS third_week,
SUM(CASE WHEN TO_CHAR(d.start_date, 'IW') = '04' THEN 1 ELSE 0 END) AS fourth_week
FROM p_disabilities d
JOIN p_disability_type dt ON dt.disability_id = d.id_disability
WHERE d.start_date >= DATE '2018-01-01'
AND d.start_date < DATE '2018-02-01'
AND TO_NUMBER(SUBSTR(d.birth_number, 2, 2)) >= 51
GROUP BY dt.disability_name
ORDER BY dt.disability_name;
WHERE
子句中最选择性的列是start_date,您可以从整个表中选择一个月。 Birth_number子字符串的选择性较小,因为您接受了可能的一半值。因此,适当的索引看起来像这样:
CREATE INDEX idx ON p_disabilities (start_date, TO_NUMBER(SUBSTR(d.birth_number, 2, 2)));
这是一个函数索引,其中包括我们索引的计算值。替代方案是计算的列:
ALTER TABLE p_disabilities ADD sex AS (CASE WHEN TO_NUMBER(SUBSTR(birth_number, 2, 2)) >= 51 THEN 'f' ELSE 'm' END);
然后将其索引并在查询中使用,我发现它更可读。
您可以在要在查询中使用的索引末尾的列,从加入的ID_DISANE开始,而有条件的聚合开始。然后,索引可能会这样lok:
TO_CHAR(d.start_date, 'IW')
日期/周的注释:虽然使用ISO Week是许多情况的好方法,但我在这里不合适,因为第一个ISO周可以在上一年开始,并且仅通过查看一月,您可能会度过四天的一周。考虑以某种方式更改此操作(例如,通过查看1月1-7日,8-14,...而不是)。