连接列,然后在MySQL

时间:2015-06-17 17:59:20

标签: mysql

我需要一些MySQL问题的帮助。我正在尝试连接两列,然后将结果插入到单个临时列中。但是,应在temp列中基于范围对连接的行进行分组。我对任何建议持开放态度,因为我的mysql经验有限。这就是我所拥有的;

现状

  • 我有两张桌子

一个包含单独的圣经经文;

CREATE temporary TABLE `bible_text_temp` (
`text_id` int(11) NOT NULL AUTO_INCREMENT, 
`book_index` varchar(50) NOT NULL DEFAULT '0',
`chapter` int(11) NOT NULL DEFAULT '0',
`verse` int(11) NOT NULL DEFAULT '0',
`verse_text` varchar(8000) NOT NULL DEFAULT '0',
`version_id` int(11) NOT NULL DEFAULT '0',
`life_verse_id` int(11) DEFAULT NULL,
`verse_html` varchar(50) DEFAULT NULL,PRIMARY KEY (`text_id`),UNIQUE KEY  `text_id_UNIQUE` (`text_id`)) 

另一张表中有特定类别的经文编号。例如。该表包含与爱有关的所有诗歌编号;

CREATE TABLE `final_verse_import` (`id` int(11) NOT NULL AUTO_INCREMENT, `book_index` varchar(500) NOT NULL, `chapter` int(11) NOT NULL, `verse_from` int(11) NOT NULL, `verse_to` int(11) DEFAULT NULL, `life_category` varchar(250) DEFAULT NULL,`life_tag_1` varchar(250) DEFAULT NULL,`life_tag_2` varchar(250) DEFAULT NULL,`verses` varchar(5000) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=2047 DEFAULT CHARSET=latin1;
  • 我正在尝试将verse_html表中的verse_textbible_text_temp列连接成经文并将其插入到另一个临时表中,名为hold_verses使用以下查询加入final_verse_import

    INSERT INTO hold_verses (book_index, chapter, verse_from, verse_to, verses)
    SELECT a.book_index, a.chapter, b.verse_from, b.verse_to, GROUP_CONCAT(DISTINCT a.verse_html, a.verse_text SEPARATOR ' ') AS verses 
    FROM bible_text_temp  a
    INNER JOIN  final_verse_import b
    ON a.book_index = b.book_index
    AND a.chapter = b.chapter
    AND a.verse = b.verse_from
    AND a.version_id = 3
    GROUP BY id
    
  • 如果我只想要final_verse_import表中每一行的第一节,上面的查询似乎工作正常。这意味着如果我只想返回,CONCAT表格中hold_verses列的verse_from列中的每个诗句行都会获得正确的final_verse_importCONCAT栏中的一节

  • 但是,final_verse_import中的某些行包含多个节目。例如,关于爱的圣经经文可以包含多个经文,例如romans 4: 2 - 4(多节经文),而不仅仅是romans 4:2(单节经文)。为了适应这种情况,我在final_verse_import表中有另一个名为verse_to的列。如果填充此列,则对于类别的行,将有多个经文。如果它没有填充(NULL),那么只有一节经文。例如。对于romans 4:2 -4verse_from将为2,而verse_to将为4。请注意,类别诗歌将是2和4之间的所有内容,因此它将是第2节,第3节,第4节。
  • 我想基于verse_fromverse_to作为CONCAT列中的hold_verses.verses值,而不只是返回类别诗行的所有经文第一节(verse_from)。因此,上述查询将无效,因为它只为每个类别的行返回一节经文。

问题

  1. 如何修改查询以返回verse_fromverse_to之间的所有经文作为CONCAT值,而不仅仅是verse_to值?我试图使用以下内容; AND a.verse BETWEEN b.verse_from AND b.verse_to子句中的WHERE,但似乎忽略了final_verse_import.verse_to = NULL的所有行。
  2. 如何添加final.verse_import.verse_to = NULL的结果?有些类别经文只有一节经文,我也需要将它们归还。
  3. 如何按CONCAT的顺序对hold_verses.verses列中的ASC经文列表进行排序?目前,当我使用BETWEEN语句时,不会按顺序显示具有多个诗句的行。例如。如果我为经文CONCAT返回romans 4: 2 -4值,结果将在CONCAT列中列为第2节,第4节,第3节,而不是第2节,第3节,第4节我意识到我的查询可能是错误的,所以如果我使用正确的查询,这可能会被修复。
  4. 如果我的问题和描述不明确,请提前道歉。我有一种过于复杂的习惯:)

2 个答案:

答案 0 :(得分:0)

在使用数据的应用程序中执行此操作可能更容易。换句话说,不是试图将所有内容整合到数据库中的单个字符串中,而是让调用应用程序选择多行,然后遍历行并操纵那里的数据。

答案 1 :(得分:0)

这样的事情应该这样做。

select
    ref.id,
    group_concat(txt.verse, ' ', txt.verse_text, ' ' order by txt.verse),
    group_concat('<b>', txt.verse, '</b> ', txt.verse_html, '<br/>' order by txt.verse)
from
    bible_text_temp txt
    join final_verse_import ref on 
        txt.book_index = ref.book_index 
        and txt.chapter = ref.chapter 
        and txt.verse >= ref.verse_from
        and txt.verse <= ifnull(ref.verse_to, ref.verse_from)
where
    ref.life_category = 'LOVE'
group by 
    ref.id
order by
    ref.id, txt.verse
;

这是完整的例子。

use example;

drop table if exists bible_text_temp;

drop table if exists final_verse_import;

CREATE TABLE `bible_text_temp` (
    `text_id` int(11) NOT NULL AUTO_INCREMENT, 
    `book_index` varchar(50) NOT NULL DEFAULT '0',
    `chapter` int(11) NOT NULL DEFAULT '0',
    `verse` int(11) NOT NULL DEFAULT '0',
    `verse_text` varchar(8000) NOT NULL DEFAULT '0',
    `version_id` int(11) NOT NULL DEFAULT '0',
    `life_verse_id` int(11) DEFAULT NULL,
    `verse_html` varchar(8000) DEFAULT NULL,
    PRIMARY KEY (`text_id`),
    UNIQUE KEY  `text_id_UNIQUE` (`text_id`)
)
;

CREATE TABLE `final_verse_import` (
        `id` int(11) NOT NULL AUTO_INCREMENT, 
        `book_index` varchar(500) NOT NULL, 
        `chapter` int(11) NOT NULL, 
        `verse_from` int(11) NOT NULL, 
        `verse_to` int(11) DEFAULT NULL, 
        `life_category` varchar(250) DEFAULT NULL,
        `life_tag_1` varchar(250) DEFAULT NULL,
        `life_tag_2` varchar(250) DEFAULT NULL,
        `verses` varchar(5000) DEFAULT NULL,
        PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2047 DEFAULT CHARSET=latin1;

insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 31, 'Do to others as you would have them do to you.','<html>Do to others as you would have them do to you.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 32, '"If you love those who love you, what credit is that to you? Even ''sinners'' love those who love them.','<html>"If you love those who love you, what credit is that to you? Even ''sinners'' love those who love them.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 33, 'And if you do good to those who are good to you, what credit is that to you? Even ''sinners'' do that.','<html>And if you do good to those who are good to you, what credit is that to you? Even ''sinners'' do that.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 34, 'And if you lend to those from whom you expect repayment, what credit is that to you? Even ''sinners'' lend to ''sinners,'' expecting to be repaid in full.','<html>And if you lend to those from whom you expect repayment, what credit is that to you? Even ''sinners'' lend to ''sinners,'' expecting to be repaid in full.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 35, 'But love your enemies, do good to them, and lend to them without expecting to get anything back. Then your reward will be great, and you will be sons of the Most High, because he is kind to the ungrateful and wicked.','<html>But love your enemies, do good to them, and lend to them without expecting to get anything back. Then your reward will be great, and you will be sons of the Most High, because he is kind to the ungrateful and wicked.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('LUKE', 6, 36, 'Be merciful, just as your Father is merciful.','<html>Be merciful, just as your Father is merciful.</html>');


insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('ROMANS', 12, 9, 'Love must be sincere. Hate what is evil; cling to what is good.', '<html>Love must be sincere. Hate what is evil; cling to what is good.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('ROMANS', 12, 10, 'Be devoted to one another in brotherly love. Honor one another above yourselves.', '<html>Be devoted to one another in brotherly love. Honor one another above yourselves.</html>');
insert into bible_text_temp (book_index, chapter, verse, verse_text, verse_html) values ('ROMANS', 12, 11, 'Never be lacking in zeal, but keep your spiritual fervor, serving the Lord.', '<html>Never be lacking in zeal, but keep your spiritual fervor, serving the Lord.</html>');

insert into final_verse_import (book_index, chapter, verse_from, verse_to, life_category) values ('LUKE', 6, 31, 36, 'LOVE'); 
insert into final_verse_import (book_index, chapter, verse_from, verse_to, life_category) values ('ROMANS', 12, 9, null, 'LOVE'); 

select
    ref.id,
    group_concat(txt.verse, ' ', txt.verse_text, ' ' order by txt.verse),
    group_concat('<b>', txt.verse, '</b> ', txt.verse_html, '<br/>' order by txt.verse)
from
    bible_text_temp txt
    join final_verse_import ref on 
        txt.book_index = ref.book_index 
        and txt.chapter = ref.chapter 
        and txt.verse >= ref.verse_from
        and txt.verse <= ifnull(ref.verse_to, ref.verse_from)
where
    ref.life_category = 'LOVE'
group by 
    ref.id
order by
    ref.id, txt.verse
;