SQL:查看表中值的函数

发布于 2024-12-19 07:13:52 字数 1878 浏览 1 评论 0原文

我正在使用事务数据库:一种关系数据库,其中表中的行被定义为数据库在给定时间“认为”该行的字段包含的一组值。

部分架构:

CREATE TABLE Article
(
    id INTEGER,
    PRIMARY KEY(id)
);

CREATE TABLE Article_headline
(
    Article_id INTEGER,
    headline TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

CREATE TABLE Article_body
(
    Article_id INTEGER,
    body TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

换句话说,虚拟的“Article”表具有三列:id、headline 和 body。

我可以创建临时视图来表示给定时间定义的虚拟“文章”表:

CREATE TEMPORARY VIEW Article_headline_old
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_body_old
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_old
AS SELECT id, headline, body
FROM Article, Article_headline_old, Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

每次我想要查询数据库以获取文章时,我都必须创建这三个临时视图,但我宁愿不这样做。我更愿意创建永久视图“函数”作为模式本身的一部分:

CREATE VIEW Article_headline_at(theTime)
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_body_at(theTime)
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_at(theTime)
AS SELECT id, headline, body
FROM Article,
     Article_headline_at(theTime) AS Article_headline_old,
     Article_body_at(theTime) AS Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

然后当我想从数据库中选择一篇文章时:

SELECT * FROM Article_at("2011-11-03 16:05:23");

SQL 是否有类似的功能?

I'm working with a transactional database: a relational database where a row in a table is defined as the set of values the database, at a given time, "thinks" the row's fields contain.

Part of the schema:

CREATE TABLE Article
(
    id INTEGER,
    PRIMARY KEY(id)
);

CREATE TABLE Article_headline
(
    Article_id INTEGER,
    headline TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

CREATE TABLE Article_body
(
    Article_id INTEGER,
    body TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

In other words, the virtual "Article" table has three columns: id, headline, and body.

I can create temporary views to represent the virtual "Article" table defined by a given time:

CREATE TEMPORARY VIEW Article_headline_old
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_body_old
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_old
AS SELECT id, headline, body
FROM Article, Article_headline_old, Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

I have to create these three temporary views each time I want to query the database to get an article, which I would rather not do. I would prefer to create permanent view "functions" as part of the schema itself:

CREATE VIEW Article_headline_at(theTime)
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_body_at(theTime)
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_at(theTime)
AS SELECT id, headline, body
FROM Article,
     Article_headline_at(theTime) AS Article_headline_old,
     Article_body_at(theTime) AS Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

And then when I want to select an article from the database:

SELECT * FROM Article_at("2011-11-03 16:05:23");

Does SQL have any similar functionality?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

聚集的泪 2024-12-26 07:13:52

您可以创建三个存储过程并将 theTime 作为变量传递给每个存储过程。

对于 Article_headline_at 和 Article_body_old_at 将这些存储过程插入到 Article_at 存储过程内的临时表中并执行查询。这可能是你的解决方案:

CREATE PROCEDURE Article_headline_at @theTime datetime as

SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

-----



CREATE PROCEDURE Article_body_old_at @theTime datetime as
SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

-----

CREATE PROCEDURE Article_at @theTime datetime as
IF OBJECT_ID('tempdb.dbo.#Article_headline_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_headline_at
IF OBJECT_ID('tempdb.dbo.#Article_body_old_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_body_old_at

create table #Article_headline_at (
Article_id int,
body nvarchar(max),
tt int
)

create table #Article_body_old_at (
Article_id int,
headline nvarchar(max),
tt int
)

declare @sql1 nvarchar(max)
declare @sql2 nvarchar(max)

set @sql1 = 'insert into #Article_headline_at exec #Article_headline_at @theTime = '''+ @theTime + ''''
set @sql2 = 'insert into #Article_body_old_at exec #Article_body_old_at @theTime = '''+ @theTime + ''''

exec sp_executesql @sql1
exec sp_executesql @sql2


SELECT id, headline, body
FROM Article, #Article_headline_at(theTime), #Article_body_at(theTime)
WHERE #Article_headline_old.Article_id = Article.id
AND #Article_body_old.Article_id = Article.id;

-----

所以最后你能做的就是

exec Article_at @theTime = "2011-11-03 16:05:23"

但我确信有一个更简单的方法,但这是我能想到的唯一方法。

You could create three stored procedures and pass theTime as a variable to each.

For Article_headline_at and Article_body_old_at insert these stored procedures into a temporary table inside Article_at stored procedures and do the query. This could be your solution:

CREATE PROCEDURE Article_headline_at @theTime datetime as

SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

-----



CREATE PROCEDURE Article_body_old_at @theTime datetime as
SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

-----

CREATE PROCEDURE Article_at @theTime datetime as
IF OBJECT_ID('tempdb.dbo.#Article_headline_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_headline_at
IF OBJECT_ID('tempdb.dbo.#Article_body_old_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_body_old_at

create table #Article_headline_at (
Article_id int,
body nvarchar(max),
tt int
)

create table #Article_body_old_at (
Article_id int,
headline nvarchar(max),
tt int
)

declare @sql1 nvarchar(max)
declare @sql2 nvarchar(max)

set @sql1 = 'insert into #Article_headline_at exec #Article_headline_at @theTime = '''+ @theTime + ''''
set @sql2 = 'insert into #Article_body_old_at exec #Article_body_old_at @theTime = '''+ @theTime + ''''

exec sp_executesql @sql1
exec sp_executesql @sql2


SELECT id, headline, body
FROM Article, #Article_headline_at(theTime), #Article_body_at(theTime)
WHERE #Article_headline_old.Article_id = Article.id
AND #Article_body_old.Article_id = Article.id;

-----

so at the end of it all you can do

exec Article_at @theTime = "2011-11-03 16:05:23"

but I am sure there is a easier way around but this the only way I can think of.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文