【问题标题】:basic sql : selecting the same column multiple times in one query, when each occurrence is dependent on different where clause基本sql:在一个查询中多次选择同一列,每次出现都依赖于不同的where子句
【发布时间】:2010-11-04 13:46:55
【问题描述】:

执行此查询的最佳方式是什么。我有下表

带有列的mytable

x y 
1 a
2 b
3 c

我想(在伪 sql 中)

select x as x1 ,x as x2, x as x3 from mytable where ????

x1 is x where y=a

x2 is x where y=b

x3 is x where y=c

所以我想要结果

1, 2, 3

我目前正在使用 cte 和一个非常大的数据集,我正在尝试减少查询时间,是否总是需要进行 3 次表扫描?

【问题讨论】:

  • 道歉,但我觉得这个问题令人困惑。您能否添加一些示例数据以及您认为 select 语句的结果应该是什么?谢谢。
  • 拜托,你能给出更清楚的解释吗?我不明白你的问题中的任何内容

标签: sql


【解决方案1】:

您应该使用 3 个查询。自加入时,通过适当的索引会快得多。此外,它将更具可读性。

如果您想要一个查询调用,可能是这样 :)

SELECT
(SELECT x FROM table WHERE y=1) AS x1,
(SELECT x FROM table WHERE y=2) AS x2,
(SELECT x FROM table WHERE y=3) AS x3

【讨论】:

  • 这意味着 3 次表扫描?
  • @NimChimpsky 是的。单表扫描的解决方案需要在您的应用程序中添加一些额外的逻辑
  • 我有一个非常大的数据集,这需要做七次,没有其他选择吗?
  • “单表扫描的解决方案将需要在您的应用程序中添加一些额外的逻辑”,嗯?
  • 我添加了另一个答案。希望这会做。您在应用程序中使用什么语言?
【解决方案2】:

我会这样做的:

SELECT
    tableRowA.x as x1
    tableRowB.x as x2
    tableRowC.x as x3
FROM
    table as tableRowA,
    table as tableRowB,
    table as tableRowC
WHERE
    tableRowA.y = 1
    tableRowB.y = 2
    tableRowC.y = 3

更容易理解,如果您需要每行中的多列,则可以提取更多信息

【讨论】:

  • 太棒了,这对我有用,我将它与两个等于表一起使用 =)
【解决方案3】:

在给出的示例中,只有 3 行输入和 1 行输出。我假设将涉及至少一个其他列,例如输入数据:

w  x  y
---------
w1 1  a
w1 2  b
w1 3  c
w2 4  a
w2 5  b
w2 6  c
.
.
.

要变成输出:

w  x1 x2 x3
-----------
w1 1  2  3
w2 4  5  6
.
.
.

这可以使用如下查询一次性完成:

select w,
       max(case when y = 'a' then x end) x1,
       max(case when y = 'b' then x end) x2,
       max(case when y = 'c' then x end) x3
from datatable
where y in ('a','b','c')
group by w

【讨论】:

    【解决方案4】:

    另一种解决方案:

    SELECT x, y FROM table WHERE y IN ('a', 'b')
    

    你会得到一个结果集:

    x | y
    -----
    1 | a
    2 | b
    

    然后可以在应用程序中使用此结果集以获得所需的结果。

    【讨论】:

      【解决方案5】:

      从您的问题来看,您似乎想要一个条件的最后三个实例,或者将三个不同的条件联系在一起。以下示例能否满足您的问题:

      mytable:
      (unique keys 1..n)      (col1)  
      student-id | course-id | grade
      s1           gen101      g1
      s1           cmp202      g2
      s1           psy303      g3
      s1           c4          g4
      s2           c1          g5
      

      假设我们只想要拥有三门特定课程(gen101、cmp202 和 psy303)的学生,并显示这些成绩而忽略其他任何人。

      select gen.student-id  as student-id
           , gen.grade       as gen101-gr
           , cmp.grade       as cmp202-gr
           , psy.grade       as psy303-gr
        from mytable  gen
           , mytable  cmp
           , mytable  psy
       where gen.course-id    = 'gen101'
         and gen.student-id   = cmp.student-id
         and cmp.course-id    = 'cmp202'
         and cmp.studnet-id   = psy.student-id
         and psy.course-id    = 'psy303'
      

      这应该给一行:

      student-id  gen101-gr cmp202-gr psy303-gr
      s1          g1        g2        g3
      

      希望能给你足够的工作。

      【讨论】:

        【解决方案6】:
        SELECT Case When y = 1 Then x1 When y = 2 Then x2 Else x3 End FROM mytable
        

        【讨论】:

          【解决方案7】:

          我的建议是选择按 y 列排序或分组的结果,并使用该信息将结果集拆分为多个列表以供应用程序处理。如果您只想在数据库中执行此操作,恐怕需要多次表扫描(或连接)。

          另一个解决方法是将 y 列中的信息迁移到另一个表(使用外键引用),以便能够更有效地加入。

          【讨论】:

            【解决方案8】:

            SQL Fiddle

            MySQL 5.5.32 架构设置

            CREATE TABLE Table1
                (`x` int, `y` varchar(1))
            ;
            
            INSERT INTO Table1
                (`x`, `y`)
            VALUES
                (1, 'a'),
                (2, 'b'),
                (3, 'c')
            ;
            
            CREATE TABLE mytable
                (`x` int, `y` varchar(1))
            ;
            
            INSERT INTO mytable
                (`x`, `y`)
            VALUES
                (1, 'a'),
                (2, 'b'),
                (3, 'c')
            ;
            

            查询 1

            SELECT x1.x as x1, x2.x as x2, x3.x as x3
            FROM mytable x1
            INNER JOIN mytable x2 ON x2.y='b'
            INNER JOIN mytable x3 ON x3.y='c'
            WHERE x1.y='a'
            

            Results

            | X1 | X2 | X3 |
            |----|----|----|
            |  1 |  2 |  3 |
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-03-16
              • 1970-01-01
              • 1970-01-01
              • 2014-09-29
              • 2018-05-01
              • 2013-04-23
              • 2021-10-20
              • 1970-01-01
              相关资源
              最近更新 更多