1

私はこのSQLの問題に困惑しており、誰かが簡単に選ぶことができると思います。

ランク付けされたアイテムのいくつかの日次リストを表す行を含むテーブルがあります。関連するフィールドは次のとおりです:ID、ListID、ItemID、ItemName、ItemRank、Date。

次のように、昨日リストにあったが今日はリストになかったアイテム(リスト外のアイテム)を返すクエリがあります。

Select ItemID, ListID, ItemName, convert(varchar(10),MAX(date),101) as date, COUNT(ItemName) as days_on_list 
From Table 
Group By ItemID, ListID, ItemName
Having Max(date) = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1
Order By ListID, ItemName, COUNT(ItemName)

基本的に、最大日が昨日であるレコードを探しています。これは正常に機能し、各アイテムが以前にリストに含まれていた日数を表示します(ただし、必ずしも連続している必要はありませんが、現時点では問題ありません)。

問題は、昨日のランクを確認するためにランキングを追加しようとしたときです。私は次のことを試しました:

Select ItemID, ListID, ItemName, ranking, convert(varchar(10),MAX(date),101) as date, COUNT(ItemName) as days_on_list 
From Table
Group By ItemID, ListID, ItemName, ranking
Having Max(date) = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1
Order By ListID, ItemName, ranking, COUNT(ItemName)

これにより、前のクエリよりもはるかに多くのレコードが返されるため、何かが正しくありません。同じ数のレコードが必要ですが、ランキングが含まれています。サブクエリを使用して自己結合を実行し、ItemIDが昨日発生したが今日は発生しないレコードを取得することでランクを取得できますが、カウントを取得する方法がわかりません。

これについての助けを事前に感謝します。

========解決済み==============

Select ItemID, ListID, ItemName, ranking, convert(varchar(10),MAX(date),101) as date, (Select COUNT(ItemName) From Table T3 Where T3.ItemID = T.ItemID and T3.ListID = 1) as days_on_list
from Table T
Where date = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1 and T.ItemID Not In
(select T.ItemID from Table T
    join Table T2 on T.ItemID = T2.ItemID and T.ListID = T2.ListID
    where T.date = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and T2.date = convert
(varchar(10),getdate(),101) and T.ListID = 1)
Group by ItemID, ListID, ItemName, ranking

基本的に、私が行ったのは、両方の日に表示されるすべてのアイテムを検索し、昨日表示されたが両方の日に表示されたアイテムのセットに含まれていないアイテムを検索するサブクエリを作成することでした。その後、集計関数とグループ化を正しく行うことができました。これが必要以上に複雑であっても驚かないでしょうが、私はそれを理解しており、必要に応じて変更することができ、パフォーマンスは問題ではないようです。

もう一度ありがとう!

4

4 に答える 4

2

問題はおそらく、最初の質問でグループ化されるアイテムのランキングが異なることです。

したがって、ランキングをグループに追加すると、以前よりも多くのグループが存在します。

これが事実で、それでも同じ量の行が必要な場合は、ラッピング質問でグループ化した後にランキングを含める必要があります。また、一致する行から最小ランキングまたは最大ランキングのどちらを好むかを決定する必要があります。

于 2011-02-25T21:42:05.820 に答える
1

グループを3つのフィールドでランク付けしない最初のクエリ。ランキングが追加されたクエリは、4つのフィールドでグループ化されます。したがって、グループ化はより細かい粒度で行われるため、より多くのレコードが得られる可能性があります。

クエリソリューションを提案する前に、サンプルデータセットとサンプルの目的の値を確認する必要があります。

于 2011-02-25T21:49:21.117 に答える
1

Group By by over 句を使用せずに Count を計算できます。

With Items As
    (
    Select ItemID, ListID, ItemName, Ranking, [Date]
        , Row_Number() Over( Partition By ItemID, ListID, ItemName Order By [Date] Desc ) As Num
        , Count(ItemName) Over ( Partition By ItemId, ListId, ItemName ) As DaysOnList
    From Table As T
    Where T.[Date] = DateAdd(d, -1, CURRENT_TIMESTAMP) 
        And Not Exists  (
                        Select 1
                        From Table As T2
                        Where T2.ItemID = T.ItemID
                            And T2.ListId = T.ListId
                            And T2.[Date] > T.[Date]
                        )
    )
Select ItemID, ListID, ItemName, LastDate, Ranking
From Items
Where Num = 1
Order By ListID, ItemName, DaysOnList
于 2011-02-25T22:11:01.713 に答える