9

1:nの関係を持つ2つのテーブルがあります:「content」と「versioned-content-data」(たとえば、記事エンティティとその記事で作成されたすべてのバージョン)。各「コンテンツ」のトップバージョンを表示するビューを作成したいと思います。

現在、私はこのクエリを(単純なサブクエリで)使用しています:

選択する
   t1.id、
   t1.title、
   t1.contenttext、
   t1.fk_idothertable
   t1.version
mytableからt1として
WHERE(バージョン=(SELECT MAX(バージョン)ASトップバージョン
                  mytableから
                  WHERE(fk_idothertable = t1.fk_idothertable)))

サブクエリは、実際には、特定のアイテムの最高バージョンを抽出する同じテーブルへのクエリです。バージョン管理されたアイテムは同じfk_idothertableを持つことに注意してください。

SQL Serverで、このクエリのインデックス付きビューを作成しようとしましたが、インデックス付きビューではサブクエリが許可されていないため、作成できないようです。それで...ここに私の質問があります...このクエリをJOINを使用してある種のクエリに変換する方法を考えられますか?

インデックス付きビューには次のものを含めることができないようです。

  • サブクエリ
  • 一般的なテーブル式
  • 派生テーブル
  • HAVING句

私は絶望的です。他のアイデアは大歓迎です:-)

どうもありがとう!

4

7 に答える 7

14

テーブルがすでに運用されている場合、これはおそらく役に立ちませんが、これをモデル化する正しい方法は、バージョン = 0 を永続的なバージョンにして、常に OLDER マテリアルのバージョンをインクリメントすることです。したがって、新しいバージョンを挿入するときは、次のように言います。

UPDATE thetable SET version = version + 1 WHERE id = :id
INSERT INTO thetable (id, version, title, ...) VALUES (:id, 0, :title, ...)

次に、このクエリは次のようになります

SELECT id, title, ... FROM thetable WHERE version = 0

サブクエリなし、MAX 集計なし。現在のバージョンが何であるかを常に把握できます。新しいレコードを挿入するために max(version) を選択する必要はありません。

于 2009-03-02T03:11:35.130 に答える
3

たぶん、このようなものですか?

SELECT
  t2.id,
  t2.title,
  t2.contenttext,
  t2.fk_idothertable,
  t2.version
FROM mytable t1, mytable t2
WHERE t1.fk_idothertable == t2.fk_idothertable
GROUP BY t2.fk_idothertable, t2.version
HAVING t2.version=MAX(t1.version)

勝手な推測ですが...

于 2009-03-02T01:12:53.963 に答える
0

これがどれほど効率的かはわかりませんが、次のようになります。

SELECT t1。*、t2.version
mytableASt1から
    加入 (
        mytable.fk_idothertable、MAX(mytable.version)ASバージョンを選択します
        mytableから
    )t2 ON t1.fk_idothertable = t2.fk_idothertable
于 2009-03-02T01:05:24.683 に答える
0

MAXをgroupbyを実行するテーブルエイリアスにすることができる場合があります。

次のようになります。

SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1 JOIN
   (SELECT fk_idothertable, MAX(version) AS topversion
   FROM mytable
   GROUP BY fk_idothertable) as t2
ON t1.version = t2.topversion
于 2009-03-02T01:05:33.013 に答える
0

FerranB は近かったと思いますが、グループ化の権利がまったくありませんでした:

with
latest_versions as (
   select 
      max(version) as latest_version,
      fk_idothertable
   from 
      mytable
   group by 
      fk_idothertable
)
select
  t1.id, 
  t1.title, 
  t1.contenttext,
  t1.fk_idothertable,
  t1.version
from 
   mytable as t1
   join latest_versions on (t1.version = latest_versions.latest_version 
      and t1.fk_idothertable = latest_versions.fk_idothertable);

M

于 2009-03-02T02:38:27.660 に答える
0
If SQL Server accepts LIMIT clause, I think the following should work:
SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1 ordery by t1.version DESC LIMIT 1;
(DESC - For descending sort; LIMIT 1 chooses only the first row and
DBMS usually does good optimization on seeing LIMIT).
于 2012-05-23T14:38:53.467 に答える
-2

このように...サブクエリの「mytable」は別の実際のテーブルであると思います...それでmytable2と呼びました。同じテーブルの場合、これは引き続き機能しますが、fk_idothertableは「id」になると思います。


SELECT 
   t1.id, 
   t1.title, 
   t1.contenttext,
   t1.fk_idothertable
   t1.version
FROM mytable as t1
    INNER JOIN (SELECT MAX(Version) AS topversion,fk_idothertable FROM mytable2 GROUP BY fk_idothertable) t2
        ON t1.id = t2.fk_idothertable AND t1.version = t2.topversion

お役に立てれば

于 2009-03-02T01:04:28.383 に答える