假设我有2个表
1. Artical(ID,Description,PubDate)
2. ArticalMedia(ID,ArticalID,MediaURL)
现在我想在stored procedure
中获取2个表。
我知道我们可以使用#Temp表来实现这一点。我这只是&最好的办法?或者我们还有其他方法来实现同样的目标吗?
简单的2个选择语句可能会导致错误的数据,请参阅以下示例:
select top 5 * from Artical order by PubDate desc
回归Artical的:5,4,3,2,1
select * from ArticalMedia where ArticalID in (select top 5 ID from Artical order by PubDate desc)
可以返回6,5,4,3,2的媒体。因为新的Artical可能会被插入数据库,在第一次选择&在第二次选择之前。
答案 0 :(得分:0)
尝试使用轻量级执行计划的优化查询:
SELECT A.*,AM.*
FROM ArticalMedia AS AM INNER JOIN
Article AS A ON AM.ArticleID = A.ID
WHERE (AM.ArticleID IN
(SELECT TOP (5) ID
FROM Article
ORDER BY PubDate DESC))
ORDER BY A.PubDate DESC
修改2
在SQL fn_split中创建表值函数:
CREATE FUNCTION [dbo].[fn_Split](@sText varchar(8000), @sDelim varchar(20) = ' ')
RETURNS @retArray TABLE (idx smallint Primary Key, value varchar(8000))
AS
BEGIN
DECLARE @idx smallint,
@value varchar(8000),
@bcontinue bit,
@iStrike smallint,
@iDelimlength tinyint
IF @sDelim = 'Space'
BEGIN
SET @sDelim = ' '
END
SET @idx = 0
SET @sText = LTrim(RTrim(@sText))
SET @iDelimlength = DATALENGTH(@sDelim)
SET @bcontinue = 1
IF NOT ((@iDelimlength = 0) or (@sDelim = 'Empty'))
BEGIN
WHILE @bcontinue = 1
BEGIN
--If you can find the delimiter in the text, retrieve the first element and
--insert it with its index into the return table.
IF CHARINDEX(@sDelim, @sText)>0
BEGIN
SET @value = SUBSTRING(@sText,1, CHARINDEX(@sDelim,@sText)-1)
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END
--Trim the element and its delimiter from the front of the string.
--Increment the index and loop.
SET @iStrike = DATALENGTH(@value) + @iDelimlength
SET @idx = @idx + 1
SET @sText = LTrim(Right(@sText,DATALENGTH(@sText) - @iStrike))
END
ELSE
BEGIN
--If you can’t find the delimiter in the text, @sText is the last value in
--@retArray.
SET @value = @sText
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END
--Exit the WHILE loop.
SET @bcontinue = 0
END
END
END
ELSE
BEGIN
WHILE @bcontinue=1
BEGIN
--If the delimiter is an empty string, check for remaining text
--instead of a delimiter. Insert the first character into the
--retArray table. Trim the character from the front of the string.
--Increment the index and loop.
IF DATALENGTH(@sText)>1
BEGIN
SET @value = SUBSTRING(@sText,1,1)
BEGIN
INSERT @retArray (idx, value)
VALUES (@idx, @value)
END
SET @idx = @idx+1
SET @sText = SUBSTRING(@sText,2,DATALENGTH(@sText)-1)
END
ELSE
BEGIN
--One character remains.
--Insert the character, and exit the WHILE loop.
INSERT @retArray (idx, value)
VALUES (@idx, @sText)
SET @bcontinue = 0
END
END
END
RETURN
END
然后查询将是:
DECLARE @tmp nvarchar(max);
select @tmp = stuff((select top 5 ', ', cast(id as nvarchar(max))
FROM Article
ORDER BY PubDate DESC
for xml path ('')
), 1, 2, '');
SELECT A.*,AM.*
FROM ArticalMedia AS AM INNER JOIN
Article AS A ON AM.ArticleID = A.ID
WHERE (AM.ArticleID IN (select value from dbo.fn_split(@tmp,',')))
ORDER BY A.PubDate DESC
答案 1 :(得分:0)
获取TOP 5
条记录,然后将它们加入ArticleMedia
表格:
SELECT *
FROM
(
SELECT TOP 5 ID,Description,PubDate
FROM Artical
ORDER BY PubDate DESC
) DS
INNER JOIN ArticleMedia AM
ON DS.[Id] = AM.[id]
答案 2 :(得分:0)
使用CTE保持简单:
with Top5Artical as (
select top (5) Artical.ID as ArticleID
from Artical
order by Artical.PubDate desc
),
insert into #Table1
select Top5.ArticalID,
Art.Description,
Art.PubDate
from Top5Artical as Top5
inner join Artical as Art
on Top5.ArticalID = Art.ID
order by Top5.PubDate desc;
insert into #Table2
select Top5.ArticalID,
ArtMedia.ID,
ArtMedia.URL
from Top5Artical as Top5
inner join ArticalMedia as ArtMedia
on Top5.ArticalID = ArtMedia.ArticalID
order by Top5.PubDate desc;
select * from #Table1;
select * from #Table2;