好吧,我有一个非常简单的查询 - 三列,第一列我希望按第二列分组,第三列只是一个计数。第一列ID有十几个值。第二,CODE有六个。如果我做一个简单的选择
SELECT ID,CODE,THINGIMCOUNTING FROM TABLE GROUP BY ID
我想要的是将列作为ID列的别名,以便CODE列不重复,因为多个ID可以引用相同的CODE,我不能通过没有重复 - 只想稍微清理一下。
我的第一个想法是别名,但这似乎不是Oracle SQL中的一个选项 - 例如
SELECT ID as FIRST_ID, ID as SECOND_ID, ID as THIRD_ID, CODE, THINGIMCOUNTING<BR>
WHERE FIRST_ID = "1" AND SECOND_ID="2" AND THIRD_ID="3" GROUP BY CODE
或其他相似之处。然后我读到了INTERSECT
关键字,但是当我使用它时,我得不到任何结果 - 只是列。类似
SELECT IDELECT ID,CODE,THINGIMCOUNTING FROM TABLE<BR>WHERE ID = "1" GROUP BY CODE
{
{1}}
INTERSECT
我试图单独从查询中获得一个类似矩阵的矩阵 - 我是否过于复杂?有没有一个简单,优雅的解决方案,我没有看到?谢谢!
答案 0 :(得分:1)
使用Pivot子句
非常简单Select *
from
( Select id,
code,
THINGIMCOUNTING
from table1)
Pivot
( count(THINGIMCOUNTING) for id in (1 as id1 ,
2 as id2 ,
3 as id3))
另一种方法是使用SUM / CASE
Select
code,
SUM(CASE WHEN id = 1 then 1 ELSE 0 END) id1,
SUM(CASE WHEN id = 2 then 1 ELSE 0 END) id2,
SUM(CASE WHEN id = 3 then 1 ELSE 0 END) id3
FROM
table1
GROUP BY
Code
答案 1 :(得分:0)
<强>更新强>
这个查询真的属于答案的底部,因为我最初没有提出它。但要切入追逐......这样的事情可能会返回您指定的结果集。
SELECT MIN(CASE WHEN i.rn = 1 THEN i.id END) AS id1
, MIN(CASE WHEN i.rn = 2 THEN i.id END) AS id2
, MIN(CASE WHEN i.rn = 3 THEN i.id END) AS id3
, MIN(CASE WHEN i.rn = 4 THEN i.id END) AS id4
, s.CODE
, s.cnt_
FROM ( SELECT t.CODE
, COUNT(1) AS cnt_
FROM mytable t
GROUP BY t.CODE
) s
LEFT
JOIN ( SELECT ROW_NUMBER() OVER (PARTITION BY j.CODE ORDER BY j.ID ASC) rn
, j.CODE
, j.ID
FROM mytable j
) i
ON i.CODE = s.CODE
GROUP BY s.CODE, s.cnt_
(我不得不深入研究Oracle文档,找到可以按组分配行号的分析函数的语法。)
<强> ORIGINAL 强>
我不确定您要查找的结果集。听起来你想要CODE的DISTINCT值,并希望通过不同的代码值得到counts
。
这部分很容易,对:
SELECT t.CODE
, COUNT(1)
FROM mytable t
GROUP BY t.CODE
返回
code count
---- -----
fee 4
fi 2
fo 3
如果这是您要查找的行数,以及您想要返回的count值,那么在同一行上获取与该代码对应的ID值会有点问题。
假设,
SELECT t.CODE
, t.ID
FROM mytable t
ORDER BY t.CODE, t.ID
返回:
code id
---- --
fee 2
fee 3
fee 5
fee 7
fi 11
fi 13
fo 4
fo 6
fo 8
这样,这个查询可以获取您希望为每个代码返回的ID值的“列表”,但这些ID值位于不同的行上,您希望在结果集中表示这个值,如下所示:
id1 id2 id3 id4 code count
--- --- --- --- ---- -----
2 3 5 7 fee 4
11 13 fi 2
4 6 8 fo 3
这有点问题。首先,必须在语句中指定列数,在语句运行时不能动态更改。因此,需要有一个可以返回的id值的上限。
但是,完全不清楚你真正想要的结果集。一个例子可以用很长的路来解释你想要达到的结果。
可能有一个分析函数可以轻松地执行此类型的数据透视,但使用普通的旧ANSI SQL获取此结果可能会成为一些可怕的SQL文本。
我建议查看分析函数。
正如我所看到的那样,“技巧”将在每个代码中为id值分配“行号”。
如果你可以得到一个看起来像这样的结果集,每个代码值中都有一个递增的行号:
code rn id
---- -- --
fee 1 2
fee 2 3
fee 3 5
fee 4 7
fi 1 11
fi 2 13
fo 1 4
fo 2 6
fo 3 8
然后你就可以这样了。可以使用rn rownumber生成结果集的查询(无论是什么)将作为内联视图插入到此查询中,在此处显示为i
:
SELECT MIN(CASE WHEN i.rn = 1 THEN i.id END) AS id1
, MIN(CASE WHEN i.rn = 2 THEN i.id END) AS id2
, MIN(CASE WHEN i.rn = 3 THEN i.id END) AS id3
, MIN(CASE WHEN i.rn = 4 THEN i.id END) AS id4
, s.CODE
, s.cnt_
FROM ( SELECT t.CODE
, COUNT(1) AS cnt_
FROM mytable t
GROUP BY t.CODE
) s
LEFT
JOIN (
-- SELECT code, rn, id --
) i
ON i.CODE = s.CODE
GROUP BY s.CODE, s.cnt_
使用SELECT列表中的条件表达式返回id值,具体取决于rn
的值。将rn = 1返回到第一列(在具有匹配CODE的行上),将rn = 2返回到第二列。 “技巧”实际上是在没有返回id值时,而不是'正确'的行号。我们必须将它们包含在某种聚合函数中,以便让外部查询上的GROUP BY起作用。
您可以使用分析/窗口类型函数为每个代码的每个id分配“行号”。好像我似乎有些语法(我知道这不对,我只是在捅它......)
我不确定是否可以在内联视图中使用它(我认为它可以在Oracle中使用),但我认为Oracle和SQL Server中的语法之间存在差异(以及支持的实际函数的差异) )。 MySQL完全没有这种类型的分析功能。
<强>更新强>
参考:http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions156.htm#SQLRF06100
看起来获取行号列的语法实际上是:
SELECT ROW_NUMBER() OVER (PARTITION BY j.CODE ORDER BY j.ID ASC) rn
, j.CODE
, j.ID
FROM mytable j
所以,像这样:
SELECT MIN(CASE WHEN i.rn = 1 THEN i.id END) AS id1
, MIN(CASE WHEN i.rn = 2 THEN i.id END) AS id2
, MIN(CASE WHEN i.rn = 3 THEN i.id END) AS id3
, MIN(CASE WHEN i.rn = 4 THEN i.id END) AS id4
, s.CODE
, s.cnt_
FROM ( SELECT t.CODE
, COUNT(1) AS cnt_
FROM mytable t
GROUP BY t.CODE
) s
LEFT
JOIN ( SELECT ROW_NUMBER() OVER (PARTITION BY j.CODE ORDER BY j.ID ASC) rn
, j.CODE
, j.ID
FROM mytable j
) i
ON i.CODE = s.CODE
GROUP BY s.CODE, s.cnt_