简化跨多个列的查询

时间:2011-05-31 15:27:36

标签: sql select

我有一个教室名称表,我想与几种已知的乐器进行比较。我的表共有11列,但其中4列包含部分领导者的仪器名称(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 ) 

有简化方法吗?

4 个答案:

答案 0 :(得分:2)

鉴于您的数据库结构,这段代码很好。只需确保format it nicely并拼写trombone正确。

但是,您始终可以选择调整数据库结构。

你可以:

  1. 创建一个Player表,其中包含字段PlayerIDPlayerName
  2. 创建一个Instruments表格,其中包含字段InstrumentIDInstrumentName
  3. 最后,创建一个Player_Instruments表,其中包含字段PlayerIDInstrumentID。这将仪器映射到玩家。
  4. 选择拥有小号或长号的玩家:

    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'  
    

    这里的Inner Join只会使那些有效地映射到小号和长号的玩家被包含在结果集中。

答案 1 :(得分:1)

 SELECT * FROM SECTION_INFO
 WHERE INSTRUMENT1 in ('TROMBONE', 'TRUMPET')
 or INSTRUMENT2 in ('TROMBONE', 'TRUMPET')
 or INSTRUMENT3 in ('TROMBONE', 'TRUMPET')
 or INSTRUMENT4 in ('TROMBONE', 'TRUMPET')

不是很简单,但由于您要比较多列,我看不到太多替代方案。

编辑:现在我重读了这个问题,如果你必须同时拥有长号和小号,这可能效果不佳。所以我可能在这方面失败了。 :)对不起。

答案 2 :(得分:1)

给出以下表格模式:

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 )    

答案 3 :(得分:0)

如果您的意思是想要自己简化查询脚本,那么您可以像这样重写WHERE子句:

WHERE 'trombone' IN (instrument1, instrument2, instrument3, instrument4)
  AND 'trumpet'  IN (instrument1, instrument2, instrument3, instrument4)

但我必须说,这可能会阻止数据库引擎在所述列上使用索引(如果有的话)。