多くKEEP-DENSE_RANK構造そこで私は、追加の答えに追加します。これらの状況があります情報。 オリジナルデータSQLFIDDLE:http://sqlfiddle.com/#!6/e5c6d/6 1.リーディングオラクル機能:
が select max(m.id), m.someId keep (DENSE_RANK FIRST ORDER BY m.UpdateDate desc)
from MyTable m
groupBy m.someId
私たちはグループにm.idの最大を選択する(someId、UpdateDate)UpdateDateが最大のそれはグループ(someIdがあります)
2.まっすぐ進むべき道はエラーのためが動作しません:列「MyTable.UpdateDateは」選択は無効ですリストは集約関数またはGROUP BY句のいずれにも含まれていないためです。 '直進' improoved
SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable
GROUP BY someId
SELECT someId, MIN(first_in_orderedset)
FROM
(SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable) t
GROUP BY someId;
4 noneffectiveあります。クロスが適用されます。
SELECT grouped.someId, orderedSet.FirstUpdateDate, maxInSet.first_in_orderedset FROM
(
SELECT mt.someId
FROM MyTable mt
GROUP BY mt.someId
) grouped CROSS APPLY
(
SELECT top 1 mt2.UpdateDate as FirstUpdateDate
FROM MyTable mt2
WHERE mt2.someId=grouped.someId
ORDER BY UpdateDate desc
) orderedSet CROSS APPLY
(
SELECT max(mt3.id) as first_in_orderedset
FROM MyTable mt3
WHERE mt3.someId=grouped.someId and mt3.UpdateDate=orderedSet.FirstUpdateDate
) maxInSet;
5.は今より複雑なテーブルと、より複雑なクエリを取得することができます: ORACLE:http://sqlfiddle.com/#!4/c943c/23 のSQL SERVER:http://sqlfiddle.com/#!6/dc7fb/1/0 (データは事前に生成され、それは両方のサンドボックスで同じです -
CREATE TABLE AlarmReports (
id int PRIMARY KEY,
clientId int, businessAreaId int , projectId int, taskId int,
process1Spent int, process1Lag int, process1AlarmRate varchar2(1) null,
process2Spent int, process2Lag int, process2AlarmRate varchar2(1) null,
process3Spent int, process3Lag int, process3AlarmRate varchar2(1) null
)
Oracleのクエリ:
結果) 表を比較するのは簡単ですSELECT clientId, businessAreaId, projectId,
sum(process1Spent),
sum(process2Spent),
sum(process3Spent),
MIN(process1AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process1Lag DESC),
MIN(process2AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process2Lag DESC),
MIN(process3AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process3Lag DESC)
FROM AlarmReports
GROUP BY GROUPING SETS ((),(clientId),(clientId, projectId),(businessAreaId),(clientId,businessAreaId))
SQLクエリ:
(to be continued)
実際にそこに私は、C#でwroted私のカスタム集計を置くことを計画しています。もし誰かが興味があれば、私に連絡してください...カスタム集計は、このような問題の最良の解決策ですが、それはvarcharの長さの点で未妥協ではありません。 varcharの長さごとに、 "特殊な" aggreate関数を作成する義務があります
Iを維持せずに、この1をそれを得ることはありません..それはどのように 'いくつかのグループ'なしで動作するはずだったのですか?テーブルに3つの異なるsomeIdsがあるので、私のクエリは常に私に3つのエントリを返します。あなたのクエリは、異なるsomeIdsの量に依存しない結果を返すので、間違っているはずですか? – javagirl
@javagirl - 最初に試しましたか?それはうまくいくでしょう。どのように機能するかについては、分析関数( 'OVER()...')は 'PARTITION BY'を持つことができ、全体のレベルでグループ化する必要はありません。テーブルにあるすべての行の値を返します。 – Lamak
元のデータを誤読しました。この問題はididではなくsomeidをパーティションに入れることで修正されています。 –