【问题标题】:how to combine more than one query in same table如何在同一张表中组合多个查询
【发布时间】:2012-12-14 07:14:47
【问题描述】:

我有下表:

CREATE TABLE studenttest 
(
    YEAR INT,
    DEPT VARCHAR(5),
    SEM INT,
    REGNO INT,
    NAME VARCHAR(20),
    ENGLISH VARCHAR(2),
    MATHS VARCHAR(2),
    PHYSICS VARCHAR(2),
    CHEMISTRY VARCHAR(2),
    EG VARCHAR(2),
    FOC VARCHAR(2),
    LAB1 VARCHAR(2),
    LAB2 VARCHAR(2),
    LAB3 VARCHAR(2)
)

有以下数据:

INSERT INTO studenttest 
 values
 (2010,'cse',3,1,'saravaanan','a','b','c','d','ra','f','g','h','i'),   
 (2010,'cse',3,2,'raja','ra','b','c','d','e','f','g','h','i'),
 (2010,'cse',3,3,'selvam','a','b','c','d','e','f','g','h','i')

我想查询这个数据来得到所有在任何科目中成绩不为“ra”的学生的结果集。

【问题讨论】:

  • 永远不要不好意思问。那么你将如何学习呢?!
  • @MahmoudGamal - 我删除了 OP 的那部分 - 没有问题 SO 将是一个悲伤的地方

标签: sql sql-server tsql select


【解决方案1】:
SELECT *
FROM studenttest
WHERE ENGLISH + ',' + MATHS + ',' + PHYSICS + ',' + CHEMISTRY + ',' + EG + ',' + FOC + ',' + LAB1 + ',' + LAB2 + ',' + LAB3 NOT LIKE '%ra%'

SQLFiddle上的演示

【讨论】:

  • 请检查ENGLISH 具有值'r'MATHS 具有'a' 的情况。
  • @techdo - 我们不知道'r' 是否是一个可能的等级......它不在OP 数据中
  • 这会导致大表的性能很慢,比较连接列上的值不是一个好的解决方案
【解决方案2】:

另一种方式:

SELECT * 
FROM studenttest
WHERE 'ra' NOT IN 
      (ENGLISH, MATHS, PHYSICS, CHEMISTRY, EG, FOC, LAB1, LAB2, LAB3) ;

【讨论】:

    【解决方案3】:

    只是@Mahmoud's version 的替代品UNPIVOTCTE,也可以使用UNION ALL 来完成:

    SELECT Name
    FROM
    (
      SELECT Name, ENGLISH grade, 'English' subject
      from studenttest
      union all
      SELECT Name, MATHS grade, 'MATHS' subject
      from studenttest
      union all
      SELECT Name, PHYSICS grade, 'PHYSICS' subject
      from studenttest
      union all
      SELECT Name, CHEMISTRY grade, 'CHEMISTRY' subject
      from studenttest
      union all
      SELECT Name, EG grade, 'EG' subject
      from studenttest
      union all
      SELECT Name, FOC grade, 'FOC' subject
      from studenttest
      union all
      SELECT Name, LAB1 grade, 'LAB1' subject
      from studenttest
      union all
      SELECT Name, LAB2 grade, 'LAB2' subject
      from studenttest
      union all
      SELECT Name, LAB3 grade, 'LAB3' subject
      from studenttest
    ) un
    where grade <> 'ra'
    group by name
    having count(grade) = 9
    

    UNPIVOT 执行与UNION ALL 相同的步骤,但代码更少。当您的数据不像您的表那样规范化时,这些查询非常有用。

    如果您想要所有数据(不仅仅是名称),您可以再次将上述查询重新加入到表中:

    select *
    from studenttest t
    inner join
    (
      SELECT Name
      FROM
      (
        SELECT Name, ENGLISH grade, 'English' subject
        from studenttest
        union all
        SELECT Name, MATHS grade, 'MATHS' subject
        from studenttest
        union all
        SELECT Name, PHYSICS grade, 'PHYSICS' subject
        from studenttest
        union all
        SELECT Name, CHEMISTRY grade, 'CHEMISTRY' subject
        from studenttest
        union all
        SELECT Name, EG grade, 'EG' subject
        from studenttest
        union all
        SELECT Name, FOC grade, 'FOC' subject
        from studenttest
        union all
        SELECT Name, LAB1 grade, 'LAB1' subject
        from studenttest
        union all
        SELECT Name, LAB2 grade, 'LAB2' subject
        from studenttest
        union all
        SELECT Name, LAB3 grade, 'LAB3' subject
        from studenttest
      ) un
      where grade <> 'ra'
      group by name
      having count(grade) = 9
    ) t2
      on t.name = t2.name
    

    SQL Fiddle with Demo

    【讨论】:

      【解决方案4】:

      你是这个意思吗?

      SELECT * 
      FROM studenttest
      WHERE 
          ENGLISH <> 'ra' AND
          MATHS <> 'ra' AND
          PHYSICS <> 'ra' AND
          CHEMISTRY    <> 'ra' AND
          EG  <> 'ra' AND   
          FOC <> 'ra' AND   
          LAB1 <> 'ra' AND  
          LAB2 <> 'ra' AND
          LAB3 <> 'ra'
      

      【讨论】:

        【解决方案5】:

        你可以这样做:

        WITH AllSubjectsGrades
        AS
        (
          SELECT Name, Grade
          FROM
          (
            SELECT 
              Name, 
              ENGLISH, MATHS, PHYSICS,  CHEMISTRY,
              EG,  FOC, LAB1, LAB2, LAB3
            FROM studenttest
          ) t
          UNPIVOT
          (
            grade
            FOR Subject IN(ENGLISH, MATHS, PHYSICS, CHEMISTRY,
                           EG,  FOC, LAB1, LAB2, LAB3)
          ) u
        )
        SELECT Name
        FROM AllSubjectsGrades
        WHERE GRADE <> 'ra'
        GROUP BY Name
        HAVING COUNT(GRADE) = 9;
        

        SQL Fiddle Demo

        这将只给您学生selvam,因为saravaananEG 中具有“ra”,而raja 在英语中具有“ra”。但是selvam 从来没有在任何主题中得到ra。就是这样

        GROUP BY Name
        HAVING COUNT(GRADE) = 9;
        

        做。

        【讨论】:

        • +1 因为这个脚本演示了一些不错的技术。虽然与@JW 脚本相比,它非常复杂。
        • @whytheq - 如果您知道 UNPIVOT 运算符,这并不复杂,它完成了整个工作。
        • 如果您了解CTEUNPIVOT + OP 并没有说明哪个版本的SQL-Server - 这对于CTE 来说已经足够晚了,这并不复杂? ....但是让用户接触tsql的这些部分是非常好的
        • @whytheq 这与执行UNION ALL 查询相同,有时更容易理解——请参阅我的answer below
        • @bluefeet - 在您的评论中,您说“在下面查看我的答案”,并且它有一个指向您答案的确切位置的超链接;页面滚动。你是怎么做到的?
        【解决方案6】:
        SELECT  a.*
        FROM    studenttest a
                LEFT JOIN
                (
                  SELECT regno, name
                  FROM studenttest
                  WHERE ENGLISH = 'ra' OR
                        MATHS = 'ra' OR
                        PHYSICS = 'ra' OR
                        CHEMISTRY    = 'ra' OR
                        EG  = 'ra' OR   
                        FOC = 'ra' OR   
                        LAB1 = 'ra' OR  
                        LAB2 = 'ra' OR  
                        LAB3 = 'ra'
                ) b ON a.regno = b.regno 
                       AND a.Name = b.Name   -- this line is OPTIONAL
        WHERE   b.regno IS NULL
        

        【讨论】:

        • 只是为了好奇,对于性能方面这个查询或 Mahmoud Gamal 的查询,哪个更好..
        • @satindersingh 这取决于表的索引方式。查看执行计划。
        猜你喜欢
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 2015-06-05
        • 1970-01-01
        • 2020-09-11
        • 2016-09-25
        • 1970-01-01
        相关资源
        最近更新 更多