4

紛らわしいタイトルですみません。db リクエストを介して行うことが可能かどうか教えてください。次の表があるとします

   ind_id      name                 value       date
----------- -------------------- ----------- ----------
1           a                    10          2010-01-01
1           a                    20          2010-01-02
1           a                    30          2010-01-03
2           b                    10          2010-01-01
2           b                    20          2010-01-02
2           b                    30          2010-01-03
2           b                    40          2010-01-04
3           c                    10          2010-01-01
3           c                    20          2010-01-02
3           c                    30          2010-01-03
3           c                    40          2010-01-04
3           c                    50          2010-01-05
4           d                    10          2010-01-05

すべての行をクエリしind_idて、指定された日付ごとに 1 回ずつ含める必要があります。指定された日付がない場合ind_idは、最も近い日付を取得し、それより低い日付がない場合は、ind_id + name を返します (name/ind_id のペアは等しい)ヌル付き。たとえば、日付が 2010-01-04 の場合、次の結果が期待されます。

ind_id      name                 value       date
----------- -------------------- ----------- ----------
1           a                    30          2010-01-03
2           b                    40          2010-01-04
3           c                    40          2010-01-04
4           d                    NULL        NULL

可能であれば、誰かがクエリの作成を手伝ってくれたらとてもありがたいです。SQL サーバー 2008 を使用しています。

4

7 に答える 7

5

このSQL FIDDLE DEMOをチェックしてください


with CTE_test
as 
(
    select int_id,
       max(date) MaxDate
    from test 
    where date<='2010-01-04 00:00:00:000'
    group by int_id
)
select A.int_id, A.[Value], A.[Date]
from test A
    inner join CTE_test B
       on a.int_id=b.int_id 
          and a.date = b.Maxdate
union all
select int_id, null, null 
from test 
where int_id not in (select int_id from CTE_test)
于 2013-03-28T17:13:10.320 に答える
2

(更新) 試してください:

with cte as
(select m.*,
        max(date) over (partition by ind_id) max_date,
        max(case when date <= @date then date end) over 
           (partition by ind_id) max_acc_date
 from myTable m)
select ind_id,
       name,
       case when max_acc_date is null then null else value end value, 
       max_acc_date date
from cte c
where date = coalesce(max_acc_date, max_date)

(SQLFiddleはこちら)

于 2013-03-28T17:01:14.023 に答える
1

試す

DECLARE @date DATETIME;

SET @date = '2010-01-04';

WITH temp1 AS
(
SELECT t.ind_id
, t.name
, CASE WHEN t.date <= @date THEN t.value ELSE NULL END AS value
, CASE WHEN t.date <= @date THEN t.date ELSE NULL END AS date
FROM test1 AS t
),

temp AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY ind_id ORDER BY t.date DESC) AS rn
FROM temp1 AS t
WHERE t.date <= @date OR t.date IS NULL
)

SELECT *
FROM temp AS t
WHERE rn = 1
于 2013-03-28T17:49:33.093 に答える
1

EXISTS演算子でオプションを使用する

DECLARE @date date = '20100104'
SELECT ind_id,
       CASE WHEN date <= @date THEN value END AS value,
       CASE WHEN date <= @date THEN date END AS date
FROM dbo.test57 t
WHERE EXISTS (
              SELECT 1
              FROM dbo.test57 t2
              WHERE t.ind_id = t2.ind_id AND t2.date <= @date
              HAVING ISNULL(MAX(t2.date), t.date) = t.date
              )

SQLFiddle のデモ

于 2013-03-28T17:24:17.240 に答える
1

次のようなものを使用できます。

declare @date date = '2010-01-04'

;with ids as
(
  select distinct ind_id
  from myTable
)
,ranks as
(
  select *
    , ranking = row_number() over (partition by ind_id order by date desc)
  from myTable
  where date <= @date
)
select ids.ind_id
  , ranks.value
  , ranks.date
from ids
  left join ranks on ids.ind_id = ranks.ind_id and ranks.ranking = 1

demo を使用した SQL Fiddle

DISTINCT含める値を取得するためにステートメントを使用しないのが理想的ですがind_id、この場合は必要な結果を得るためにステートメントを使用しました。

また、これらの種類のクエリに対する標準的な免責事項。重複データがある場合は、 の代わりにORDER BYまたは を使用してタイブレーカー列を検討する必要があります。RANKROW_NUMBER

OPの更新後に編集

新しい列を既存のクエリに追加するだけです。

with ids as
(
  select distinct ind_id, name
  from myTable
)
,ranks as
(
  select *
    , ranking = row_number() over (partition by ind_id order by date desc)
  from myTable
  where date <= @date
)
select ids.ind_id
  , ids.name
  , ranks.value
  , ranks.date
from ids
  left join ranks on ids.ind_id = ranks.ind_id and ranks.ranking = 1

demo を使用した SQL Fiddle

ind_id前のものと同様に、可能な場合は、スタンディング データ テーブルに結合して/name情報を取得するのが最善です。

于 2013-03-28T16:50:15.277 に答える
1

探している結果を返すクエリを次に示します。

SELECT
    t1.ind_id
,   CASE WHEN t1.date <= '2010-01-04' THEN t1.value ELSE null END
FROM test t1
WHERE t1.date=COALESCE(
    (SELECT MAX(DATE)
    FROM test t2
    WHERE t2.ind_id=t1.ind_id AND t2.date <= '2010-01-04')
,   t1.date)

ID が現在の行の ID と一致し、日付がターゲット日付 の前の最も高い日付になるように、相関クエリの行を選択するという考え方です'2010-01-04'

そのような行が存在しない場合、現在の行の日付が返されます。nullこの日付は;に置き換える必要があります。これはCASE、上部のステートメントが行っていることです。

これはsqlfiddleのデモです。

于 2013-03-28T17:08:10.663 に答える
0

これは正確な答えではありませんが、テストせずにすばやく書き留めるだけなので、コンセプトがわかります。

use
go 
if
(Select value from table where col=@col1) is not null
--you code to get the match value
else if 
(Select LOWER(Date) from table ) is not null
-- your query to get the nerst dtae record
else
--you query withh null value
end
于 2013-03-28T16:55:20.927 に答える