从一行中的表中选择2行的最佳方法是什么?

时间:2016-09-27 08:31:29

标签: mysql sql postgresql crosstab

我有一个如下表

TABLE_A
ID           PERSON_ID    NAME         GRADE
----------   ----------   ----------   ----------
1            1            NAME_1       10
2            1            NAME_1       20
3            2            NAME_2       30
4            2            NAME_2       40
...
在此表中

,对于每个名称,恰好有两行(两个等级)。 我想进行如下结果的查询

RESULT
PERSON_ID    NAME         GRADE1       GRADE_2
----------   ----------   ----------   ----------
1            NAME_1       10            20
2            NAME_2       30            40

这是最好的方法。 我可以使用自联接,但我认为这不是正确的方法

5 个答案:

答案 0 :(得分:1)

您可以像建议的其他人一样使用GROUP BY。

或者你可以加入。

select t1.person_id, t1.grade as grade1, t2.grade as grade2
from TABLE_A t1 join TABLE_A t2 on t1.person_id=t2.person_id and t1.id!=t2.id

此JOIN连接具有相同人物的所有行,但不会连接具有相同ID的行,因此您可以过滤掉重复项。

答案 1 :(得分:0)

尝试使用SQL SERVER

; WITH CTE AS(
SELECT PERSON_ID, NAME, GRADE AS GRADE_1, 
LEAD(GRADE) OVER(PARTITION BY NAME ORDER BY NAME) AS GRADE_2 
FROM TABLE_A
) 
SELECT * FROM CTE 
WHERE GRADE_2 IS NOT NULL

RESULT SET:

PERSON_ID    NAME         GRADE_1       GRADE_2
----------   ----------   ----------   ----------
1            NAME_1       10            20
2            NAME_2       30            40

答案 2 :(得分:0)

如果您使用的是MySQL,并且如果所有名称都有两个记录,并且第一个等级是id较低的等级而另一个等级是另一个等级,那么您可以使用类似这样的查询:

select
  person_id,
  name,
  group_concat(grade order by id) as grades
from
  table_a
group by
  person_id,
  name

然后,如果您想将成绩分成两个新列,您可以使用SUBSTRING_INDEX:

select
  person_id,
  name,
  substring_index(group_concat(grade order by id), ',', 1) as grade1,
  substring_index(group_concat(grade order by id), ',', -1) as grade2
from
  table_a
group by
  person_id,
  name

答案 3 :(得分:0)

一旦主题入门者没有提及等级的顺序和“正好有两行(两个等级)”,我认为最简单的方法:

        <java classname="com.google.gwt.dev.codeserver.CodeServer">
        <classpath>
            .
            .
            .
            <pathelement location=".apt_generated"/>
            .
            .
            .
        </classpath>

答案 4 :(得分:-1)

我在这个链接中找到了PostgreSQL的最佳答案 https://www.postgresql.org/docs/9.2/static/tablefunc.html 在PostgreSQL中有crosstab(text)函数。

  

交叉表功能用于生成“数据透视”显示,其中数据在页面中列出而不是向下。例如,我们可能有像

这样的数据
row1    val11
row1    val12
row1    val13
...
row2    val21
row2    val22
row2    val23
...
  

我们希望显示为

row1    val11   val12   val13   ...
row2    val21   val22   val23   ...
...
  

crosstab函数接受一个text参数,该参数是一个SQL查询,用于生成以第一种方式格式化的原始数据,并生成以第二种方式格式化的表。   sql参数是一个生成源数据集的SQL语句。   此语句必须返回一个row_name列,一列category列和一个value列。 N是一个过时的参数,如果提供则会被忽略(以前这必须与输出值列的数量匹配,但现在由调用查询确定)。   例如,提供的查询可能会生成类似于以下内容的集合:

row_name    cat    value
----------+-------+-------
  row1      cat1    val1
  row1      cat2    val2
  row1      cat3    val3
  row1      cat4    val4
  row2      cat1    val5
  row2      cat2    val6
  row2      cat3    val7
  row2      cat4    val8
  

声明crosstab函数返回setof record,因此必须在调用FROM语句的SELECT子句中定义输出列的实际名称和类型,例如:

SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);
  

此示例生成类似以下内容的集合:

           <== value  columns  ==>
 row_name   category_1   category_2
----------+------------+------------
  row1        val1         val2
  row2        val5         val6

有关更多阅读部分 F.35.1.2。在网址中输入了答案

相关问题