简化跨多列的查询

问题描述

| 我有一张要与几种已知仪器进行比较的教室名称表。我的表共有11列,但其中四列包含节长工具名称(instrument1 ... instrument4)。我想创建一个sql语句,将要查找的两种工具与每行每一列中出现的四个名称进行比较。 例如我需要找到小号和长号 我认为它看起来像这样。 这是我的陈述
SELECT *
FROM   section_info
WHERE  ( instrument1 = trombone
          OR instrument2 = trombone
          OR instrument3 = trombone
          OR instrument4 = trombone )
       AND ( instrument1 = trumpet
              OR intsrument2 = trumpet
              OR instrument3 = trumpet
              OR instrument4 = trumpet ) 
有没有一种方法可以简化?     

解决方法

        给定您的数据库结构,此代码就可以了。只需确保将其格式化良好并正确拼写长号即可。 但是,您始终可以选择调整数据库结构。 你可以: 创建一个
Player
表,该表具有字段
PlayerID
PlayerName
。 创建一个
Instruments
表,该表具有字段
InstrumentID
InstrumentName
。 最后,创建一个
Player_Instruments
表,该表具有字段
PlayerID
InstrumentID
。这会将乐器映射到玩家。 选择拥有小号或长号的玩家:
SELECT *
FROM   players AS P
       INNER JOIN player_instruments AS PI ON PI.PlayerID = P.PlayerID 
       INNER JOIN instruments AS I ON I.InstrumentID = PI.InstrumentID
WHERE  I.InstrumentName = \'trumpet\'
        OR I.InstrumentName = \'trombone\'  
选择拥有小号和长号的玩家:
SELECT *
FROM   players AS P
       INNER JOIN player_instruments AS TRUMP ON TRUMP.playerid = P.playerid
       INNER JOIN instruments AS TRUMP_I ON TRUMP_I.instrumentid = TRUMP.instrumentid AND TRUMP_I.InstrumentName = \'trumpet\'
       INNER JOIN player_instruments AS TROM ON TROM.playerid = P.playerid
       INNER JOIN instruments AS TROM_I ON TROM_I.instrumentid = TROM.instrumentid AND TROM_I.InstrumentName = \'trombone\'  
此处的“内部联接”仅将那些有效映射到小号和长号的球员包括在结果集中。     ,        
 SELECT * FROM SECTION_INFO
 WHERE INSTRUMENT1 in (\'TROMBONE\',\'TRUMPET\')
 or INSTRUMENT2 in (\'TROMBONE\',\'TRUMPET\')
 or INSTRUMENT3 in (\'TROMBONE\',\'TRUMPET\')
 or INSTRUMENT4 in (\'TROMBONE\',\'TRUMPET\')
并没有简单得多,但是由于您正在比较多个列,因此我看不到其他选择。 编辑:现在,我重新阅读了该问题,如果您必须同时拥有长号和小号,则可能无法正常工作。所以我可能在此方面失败了。 :)对不起。     ,        给定以下表模式:
CREATE TABLE `instruments` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,`instrument` VARCHAR(50) NULL DEFAULT NULL,PRIMARY KEY (`id`)
)
COLLATE=\'utf8_general_ci\'
ENGINE=InnoDB

CREATE TABLE `section_info` (
    `instrument1` INT(10) NULL DEFAULT NULL,`instrument2` INT(10) NULL DEFAULT NULL,`instrument3` INT(10) NULL DEFAULT NULL,`instrument4` INT(10) NULL DEFAULT NULL
)
COLLATE=\'utf8_general_ci\'
ENGINE=InnoDB
您可以执行以下操作:
SELECT si.*,inst_1.instrument,inst_2.instrument,inst_3.instrument,inst_4.instrument      
FROM section_info si                                                                         
    LEFT JOIN instruments as inst_1 ON si.instrument1=inst_1.id                               
    LEFT JOIN instruments as inst_2 ON si.instrument2=inst_2.id                               
    LEFT JOIN instruments as inst_3 ON si.instrument3=inst_3.id                               
    LEFT JOIN instruments as inst_4 ON si.instrument4=inst_4.id                               

WHERE                                                                                        
    # instrument 1 is a trombone...                                                           
    ( si.instrument1 = 1 OR si.instrument2 = 1 OR si.instrument3 = 1 OR si.instrument4 = 1 )  
    AND                                                                                       
    # instrument 2 is a trumpet...                                                            
    ( si.instrument1 = 2 OR si.instrument2 = 2 OR si.instrument3 = 2 OR si.instrument4 = 2 )    
    ,        如果您想自己简化查询脚本,则可以这样重写WHERE子句:
WHERE \'trombone\' IN (instrument1,instrument2,instrument3,instrument4)
  AND \'trumpet\'  IN (instrument1,instrument4)
但是我必须说,这可能会阻止数据库引擎使用所述列上的索引(如果有)。