2

注意:这个问题对“学位”有一个模棱两可的概念。我已经得到了答案。

这些天来,我正在努力解决如下问题:您不能使用某种编程语言编写函数;仅使用 RAW SQL。

给定一个articles包含 2 列的表:article_idtag_name

article_id  |  tag_name
---------------------------
1              C++
1              java
1              python
2              ruby
2              js
3              ruby
4              java
4              python

和一个名为“tag_relations”的空表,其结构如下:

tag1     |   tag2    |  degree
-----------------------------------

现在,问题来了:

  • 根据第一个表的内容编写“RAW SQL”以将值写入表“tag_relations”。

对于给定的数据,输出应该是这样的(我不确定学位是多少,问题也没有提到,所以,戈登·林诺夫和乔纳森·莱夫勒的答案对我来说都是正确的。):

tag1     |   tag2    |  degree
-----------------------------------
java         C++        2
java         python     4
ruby         js         2

更新的附加信息

注意1.这里的“程度”没有被问题描述。但是我认为这是衡量 2 个标签之间关系的指标。因为有 'java' 和 'C++' 的值:

article_id  |  tag_name
---------------------------
1              C++
1              java

所以度数 = 2

对于“java”和“python”

article_id  |  tag_name
---------------------------
1              java
1              python
4              java
4              python

所以度数 = 4

注意2:
没有学位记录:'python'和'C++',(我的意思是这个问题不涉及这种情况degree < 2)(编辑注意:此评论与在输出中包含C++和Java不一致。 )

我在这个问题上花了一天时间,并回顾了我对 SQL 的了解,但仍然不知道如何存储变量或循环记录。

任何想法将不胜感激!

4

2 回答 2

6

学位是什么?它似乎是连接两件事的最大文章 ID。

此查询需要自连接(和插入):

insert into tag_relations(tag1, tag2, degree)
    select a1.tag_name, a2.tag_name, max(article_id) as maxid
    from articles a1 join
         articles a2
         on a1.article_id = a2.article_id and
            a1.tag_name < a2.tag_name
    group by a1.tag_name, a2.tag_name

自联接查找具有相同 article_id 的所有项目对。"<" 只是确保反转订单不会创建新对。对于任何pair,都取最大article_id 作为新的度数。

于 2012-08-29T01:07:59.233 回答
3

由于问题中的数据不连贯(或解释不连贯),因此这个答案对一些产生看似合理的答案的假设有轻微的自由。

假设目标是列出每对标签应用于同一文章 ID 的次数。给定数据:

article_id  |  tag_name
---------------------------
1              c++
1              java
1              python
2              ruby
2              js
3              ruby
4              java
4              python

预期的输出可能是:

tag1     | tag2    | degree
------------------------------
c++        java      1      -- from 1
java       python    2      -- from 1 and 4
c++        python    1      -- from 1 (missing from question's expected results)
java       ruby      1      -- from 2

标签是排序的,以便在;tag1之前排序 tag2这样可以避免 ( java, java) 出现,也可以防止 ( c++, java) 与 ( java, c++) 一起出现。

鉴于对问题的所有这些解释,我们需要开发一个查询来选择数据,然后将其附加到INSERT INTO tag_relations.

SELECT a.article_id, a.tag_name AS tag1, b.tag_name AS tag2
  FROM articles AS a
  JOIN articles AS b ON a.article_id = b.article_id AND a.tag_name < b.tag_name;

这里的关键概念是“自加入”。该表articles在查询中被使用了两次(并被赋予了两个不同的别名以明确哪个是哪个),并且该表与其自身连接。这里的连接细节是一种很常见的模式;在某些列上相等,但在一个或多个其他列上不相等。如果有几列要排序,排序条件就会变得棘手。有时,这将是 a<=而不是<.

这给出了输出:

1    c++      java
1    c++      python
1    java     python
2    js       ruby
4    java     python

现在我们只需要用 COUNT 来总结一下学位:

SELECT a.tag_name AS tag1, b.tag_name AS tag2, COUNT(*) AS degree
  FROM articles AS a
  JOIN articles AS b ON a.article_id = b.article_id AND a.tag_name < b.tag_name
 GROUP BY tag1, tag2;

如果要计算反向关系以及正向关系,则可以将计数乘以 2;这将更接近您的预期数据。

最后插入数据,我们得到:

INSERT INTO tag_relations(tag1, tag2, degree)
    SELECT a.tag_name AS tag1, b.tag_name AS tag2, COUNT(*) AS degree
      FROM articles AS a
      JOIN articles AS b ON a.article_id = b.article_id AND a.tag_name < b.tag_name
     GROUP BY tag1, tag2;
于 2012-08-29T01:16:00.983 回答