用于优先匹配模式/文本的MySQL逻辑

时间:2016-08-18 17:48:00

标签: mysql sql

我有一张有short_description的事件表。我正在尝试根据short_description中的文本将它们分配到一个类别(不太理想,我知道,但我正在使用现有系统并且没有太多控制权)。所以我创建了一个查找表,其中包含要查找的search_text,以及应该分配给事件的类别值。在某些情况下,多个search_text值与short_description匹配。我希望在发生这种情况时使用优先级字段来选择最高优先级(最低优先级值,例如1)。我觉得这可能涉及窗口功能或其他东西,但我不确定如何处理它。

有人可以帮我解决下面逻辑中所需的更改吗?

谢谢!

下面的查询返回两个结果,但我希望它只返回一个(群集),因为群集优先级为1,磁盘优先级为2.我只需要每个狙击一个记录(事件)。

CREATE TABLE snow_incident_s_2 (
  SNUMBER varchar(40) DEFAULT NULL,
  SHORT_DESCRIPTION varchar(200) DEFAULT NULL
);

INSERT INTO snow_incident_s_2 (snumber, short_description) values ('INC15535802','Prognosis::ADMINCLUSTER [5251]::CmaDiskPartitionNearFull, PROGNOSIS:ADMINCLUSTER');

CREATE TABLE lkp_incident_category_2 (
  incident_category_id smallint(6) NOT NULL AUTO_INCREMENT,
  incident_type varchar(10) DEFAULT NULL,
  category varchar(100) NOT NULL,
  search_text varchar(200) NOT NULL,
  priority smallint(6) DEFAULT NULL,
  PRIMARY KEY (incident_category_id)
);

INSERT INTO lkp_incident_category_2 (incident_type, category, search_text, priority) values ('INC','Cluster','Cluster',1);
INSERT INTO lkp_incident_category_2 (incident_type, category, search_text, priority) values ('INC','Disk','Disk',2);

SELECT 
    inc.snumber,
    inc.short_description,
    ic.search_text,
    ic.category
FROM
    snow_incident_s_2 inc
        LEFT JOIN
    lkp_incident_category_2 ic ON inc.short_description LIKE CONCAT('%', ic.search_text, '%')
        AND ic.incident_type = 'INC'

2 个答案:

答案 0 :(得分:0)

以下是如何使用窗口函数。

我不得不说ON inc.short_description LIKE CONCAT('%', ic.search_text, '%')会很慢。如果这是偶然的(像每天一样)作为一个临时的,它会很好,但如果经常这样做(每小时,每分钟或更多),你会想要实现这些价值的存在因为除非使用完整的文本查询或NOSQL解决方案,否则无法为它们创建索引。

SELECT snumber, short_description, search_text, category
FROM (
  SELECT snumber, short_description, search_text, category,
         ROW_NUMBER() OVER (partition by snumber order by priority asc) as rn
  FROM (
    SELECT 
      inc.snumber,
      inc.short_description,
      ic.search_text,
      ic.category,
      ic.priority
    FROM snow_incident_s_2 inc
    LEFT JOIN lkp_incident_category_2 ic 
      ON inc.short_description LIKE CONCAT('%', ic.search_text, '%') 
      AND c.incident_type = 'INC'
  ) X
) Y
WHERE RN = 1

答案 1 :(得分:0)

mysql中不存在

窗口函数。但你可以使用变量来模仿它们。

我一直试图测试这个,但是sqlfiddle没有合作,所以这里是我认为应该为你试一试。

SELECT *
FROM (
  SELECT 
      inc.snumber
      ,inc.short_description
      ,ic.search_text
      ,ic.category
      ,(@rownum := IF(@incnum=inc.snumber,@rownum+1,1)) as IncidentRowNum
      ,@incnum := inc.snumber
  FROM
      snow_incident_s_2 inc
      LEFT JOIN lkp_incident_category_2 ic
      ON inc.short_description LIKE CONCAT('%', ic.search_text, '%')
      AND ic.incident_type = 'INC'
      CROSS JOIN (SELECT @rownum := 0, @incnum := '') var
  ORDER BY
    ic.priority
) t
WHERE
 t.IncidentRowNum = 1
;

这里经过全面测试和运作,是http://sqlfiddle.com/#!9/75ff1/7

的平方英尺