私はかなり興味深い問題に直面しています。次の構造を持つテーブルがあります。
CREATE TABLE [dbo].[Event]
(
Id int IDENTITY(1,1) NOT NULL,
ApplicationId nvarchar(32) NOT NULL,
Name nvarchar(128) NOT NULL,
Description nvarchar(256) NULL,
Date nvarchar(16) NOT NULL,
Time nvarchar(16) NOT NULL,
EventType nvarchar(16) NOT NULL,
CONSTRAINT Event_PK PRIMARY KEY CLUSTERED ( Id ) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
)
)
したがって、問題は、このデータをグリッドに表示する必要があることです。 2つの要件があります。 1つ目は、どのアプリケーションがそれらをスローしたかに関係なく、すべてのイベントを表示することです。これは簡単です-選択ステートメントは非常に簡単に仕事をします。
2番目の要件は、Application
でイベントをグループ化できることです。言い換えると、ApplicationId
が複数回繰り返された場合に、すべてのアプリケーションの最後のエントリのみを取得するように、すべてのイベントを表示します。この時点でのイベントの主キー(Id)は、このクエリ/ビューでは不要になりました。
また、イベントの日付と時刻が文字列形式であることに気付くかもしれません。これは、標準の日付/時刻形式(mm/dd/yyyyおよびhh:mm:ss)に従うため、問題ありません。私は次のようにそれらを引き出すことができます:
Convert( DateTime, (Date + ' ' + Time)) AS 'TimeStamp'
私の問題は、残りの列でAGGREGATE関数を使用した場合、どのように動作するかわからないことです。
SELECT
ApplicationId,
MAX(Name),
MAX(Description),
MAX( CONVERT(DateTime, (Date + ' ' + Time))) AS 'TimeStamp',
MAX( EventType )
FROM
Event
GROUP BY
ApplicationId
私がそうするのをためらう理由は、MAX
などの関数が、レコードの(サブセット)セットから特定の列の最大値を返すためです。最後のレコードを引く必要はありません!
アプリケーションごとに最後のレコードのみを選択する方法に関するアイデアはありますか?
SQL Server 2012以降、簡単に
SELECT
[Month]
, [First] = FIRST_VALUE(SUM([Clicks])) OVER (ORDER BY [Month])
, [Last] = FIRST_VALUE(SUM([Clicks])) OVER (ORDER BY [Month] DESC)
FROM
[dbo].[Table]
GROUP BY [Month]
ORDER BY [Month]
6年後、SQL Serverの別の答え:
select t1.[Id], t2.[Value]
from [dbo].[Table] t1
outer apply (
select top 1 [Value]
from [dbo].[Table] t2
where t2.[Month]=t1.[Month]
order by [dbo].[Date] desc
)
私はPostgresqlソリューションが好きですが、入力するのに優れており、はるかに効率的な独自のオン機能を備えています:
select distinct on (id),val
from tbl
order by id,val
Group byでサブクエリを使用できます-group by引数はselectにある必要はありません。これは、IDが自動インクリメントされ、最大のものが最新のものであると想定しています。
SELECT
ApplicationId,
Name,
Description,
CONVERT(DateTime, (Date + ' ' + Time)) AS 'TimeStamp',
EventType
FROM
Event e
WHERE
Id in (select max(Id) from Event GROUP BY ApplicationId)
私はそれが最後に挿入されたレコードをフェッチするために喜んでそこに多くの人のために働くと思うとそれはグループ化する必要があります:
select * from(select * from TableName ORDER BY id DESC)AS x GROUP BY FieldName
次の場合に機能します。
テーブル構造 ID名前ステータス1 Junaidはい2 Jawadいいえ3 Fahadはい4 Junaidいいえ5 Kashifはい
上記のクエリ後の結果 ID Name Status 4 Junaid No 2 Jawad No 3 Fahad Yes 4 Kashif Yes
名前によるグループの最後のレコードの結果です。
SELECT
E.ApplicationId,
E.Name,
E.Description,
CONVERT(DateTime, (E.Date + ' ' + E.Time)) AS 'TimeStamp',
E.EventType
FROM
Event E
JOIN (SELECT ApplicationId,
MAX(CONVERT(DateTime, (Date + ' ' + Time))) AS max_date
FROM Event
GROUP BY ApplicationId) EM
on EM.ApplicationId = E.ApplicationId
and EM.max_date = CONVERT(DateTime, (E.Date + ' ' + E.Time)))
そこにはwhere句がないため、レコードのサブセットはすべてのレコードです。しかし、あなたは間違った列に最大値を入れていると思います。このクエリは、あなたが探しているものを提供します。
Select max(applicationid), name, description, CONVERT(DateTime, (Date + ' ' + Time))
from event
group by name, description, CONVERT(DateTime, (Date + ' ' + Time))
これを行うには、サブクエリまたはCTEテーブルを使用できます。
;WITH CTE_LatestEvents as (
SELECT
ApplicationId,
MAX( CONVERT(DateTime, (Date + ' ' + Time))) AS 'LatestTimeStamp',
FROM
Event
GROUP BY
ApplicationId
)
SELECT
ApplicationId,
Name,
Description,
CONVERT(DateTime, (Date + ' ' + Time))) AS 'TimeStamp',
EventType
FROM
Event e
Join CTE_LatestEvents le
on e.applicationid = le.applicationid
and CONVERT(DateTime, (e.Date + ' ' + e.Time))) = le.LatestTimeStamp