about me

Nên tìm hiểu sâu về SQL Server

| 30 thg 11, 2009

xin giúp về câu lênh SQL

Hi.
Tôi đang làm website tin tức, tại cuối mỗi bản tin thì có phần các tin cùng chủ đề, phần này tôi muốn phân ra làm 2 phần, 1 là 10 tin mới nhất của chủ đề đó, phần này đã đc giải quyết bằng lênh select top 10...
Hiện tại phần 2 tôi muốn là 10 tin tiếp theo của tin đang đọc, cái này thì tôi ko biết phải dùng lênh SQL như thế nào ? Các pac nào có kinh nghiệm thì chỉ giúp. Xin cảm ơn nhiều,
Reply With Quote
  #2  
Old 28-06-2009, 20:56
hoangchau's Avatar
Registered User
 
Tham gia: 29-11-2004
Location: Đà Nẵng
Bài viết: 220
Bảng lưu trữ tin tức của bạn phải có field dạng như lastread [datetime] mỗi khi người đọc click vào "chi tiết tin" chẳng hạn thì cập nhật ngày giờ vào field này.

Hiển thị 10 tin đang đọc chỉ đơn giản là select 10 tin đọc gần nhất thôi
Reply With Quote
  #3  
Old 28-06-2009, 21:26
Registered User
 
Tham gia: 08-07-2007
Bài viết: 190
Quote:
Được gửi bởi hoangchau View Post
Bảng lưu trữ tin tức của bạn phải có field dạng như lastread [datetime] mỗi khi người đọc click vào "chi tiết tin" chẳng hạn thì cập nhật ngày giờ vào field này.

Hiển thị 10 tin đang đọc chỉ đơn giản là select 10 tin đọc gần nhất thôi
ko phải bạn ạ, chắc bạn chưa hiểu ý mình. hiện tại có dantri.com dang làm cách này. Khi bạn đọc 1 tin thì bên dứoi có 2 phần tin cùng chủ đề, phần đầu là 10 tin mới nhất (nếu có) của chủ đề đó, phần sau cũng là 10 tin của chủ đề, nhưng là 10 tin tiếp theo của tin đang đọc (theo thứ tự cũ dần).
Reply With Quote
  #4  
Old 28-06-2009, 21:53
webvina's Avatar
Registered User
 
Tham gia: 19-04-2009
Bài viết: 52
P2 : bác cứ select top 10......where ngaytao < ngaytao của tin tức hiện tại
Reply With Quote
  #5  
Old 28-06-2009, 22:00
Registered User
 
Tham gia: 08-07-2007
Bài viết: 190
éc, từ ý kiến của pac Webvina em nghĩ ra rồi, chỉ cần thêm newsId < newsId hiện tại là ok 
Reply With Quote
  #6  
Old 28-06-2009, 22:45
dq_ninh's Avatar
Registered User
 
Tham gia: 20-02-2009
Location: Seattle
Bài viết: 407
Quote:
Được gửi bởi tungoso View Post
éc, từ ý kiến của pac Webvina em nghĩ ra rồi, chỉ cần thêm newsId < newsId hiện tại là ok 
Một là như thế. Nhưng nếu newsID < newsID không giải quyết được (vì bạn phải tồn giữ newsId thứ 10 ở đâu đó), thì bạn có thể viết query như thế này:

SELECT TOP 10 col1, col2,...
FROM ***
WHERE newsId NOT EXISTS(SELECT TOP 10 newsId FROM ***)

(*** Viết xuất kỳ bất ý, chưa kiểm chứng)

Viết như trên có hai cái lợi: 1) không phải giữ biến từ cho newsId, và 2) luôn luôn lấy được những tin mới cập nhật.
Reply With Quote
  #7  
Old 01-07-2009, 01:15
chauxauxi's Avatar
Registered User
 
Tham gia: 01-07-2009
Bài viết: 28
Trả lời hơi giống bạn trên nhưng có Test roài

Mình làm như sau, có gì bạn chưa giải quyết được có thể xem qua, nếu làm được roài cũng xin đóng góp vậy:

Select top 10 newID,col1,...
from NEWS
where
newID Not In ( Select top 10 newID from NEWS)

Test rồi và cho kết quả đúng, chúc bạn làm tốt nhen...

Mình có thêm một cách nữa, cung cấp lun hen:

Select * from ( select top 10 newID
from ( Select top 20 newID from NEWS) As KQ1
Order by newID desc ) As KQ2
Order by newID asc


P/S: Bạn viết bài ở trên mình đừng chửi mình nha, tại mình đọc y/c của tác giả xong trả lời mà ko có nhìn câu trả lời của bạn, hơi giống hen. Thông cảm...

Được sửa bởi chauxauxi lúc 01:31 ngày 01-07-2009.
Reply With Quote
  #8  
Old 01-07-2009, 03:14
dq_ninh's Avatar
Registered User
 
Tham gia: 20-02-2009
Location: Seattle
Bài viết: 407
Quote:
Được gửi bởi chauxauxi View Post
Mình làm như sau, có gì bạn chưa giải quyết được có thể xem qua, nếu làm được roài cũng xin đóng góp vậy:

Select top 10 newID,col1,...
from NEWS
where
newID Not In ( Select top 10 newID from NEWS)

Test rồi và cho kết quả đúng, chúc bạn làm tốt nhen...

Mình có thêm một cách nữa, cung cấp lun hen:

Select * from ( select top 10 newID
from ( Select top 20 newID from NEWS) As KQ1
Order by newID desc ) As KQ2
Order by newID asc


P/S: Bạn viết bài ở trên mình đừng chửi mình nha, tại mình đọc y/c của tác giả xong trả lời mà ko có nhìn câu trả lời của bạn, hơi giống hen. Thông cảm...
Hehehe. ờ ờ ờ, đúng rồi. Not IN(***) thì đúng hơn, mà not exists(....) thì sai vì còn thiếu cái WHERE clause.

Nhưng đã nói là viết "Xuất kỳ bất ý" mà. Cái quan trọng chính là ý tưởng.
Reply With Quote
  #9  
Old 01-07-2009, 21:41
chauxauxi's Avatar
Registered User
 
Tham gia: 01-07-2009
Bài viết: 28
Xin lỗi vì đã không hiểu rõ câu hỏi

Cám ơn bạn dq_ninh đã nhắc nhở, mình đọc đề ko kỹ:
Bài trước mình viết cũng chưa đúng lắm, mình sửa lại tý, vì tin gần nhất tức là cũ dần nên mình phải sắp xếp theo thời gian lại.
Lấy ra 10 tin mới nhất:
G/S: Bạn có thuộc tính ngày tháng đăng tin ( timeNews - chắc là có đúng ko bạn)

Select top 10 newID,col1,...
from NEWS
where
newID Not In ( Select top 10 newID from NEWS )
Order by timeNews desc

Bây giờ là yêu cầu thứ hai, xuất ra top 10 tin cũ dần tiếp theo từ tin đang đọc, vậy tin đang đọc mặc dù là ngẫu nhiên nhưng chắc chắn sẽ có một ID, mình giả sử bạn sẽ có một newID ( mã của tin đang đọc )
Mình thực hiện bằng procedure như sau :


create proc sp_OutTop10
@newID int
AS
Begin
Select newID,col1,... into #Temp from NEWS Order by timeNews desc ---vì là 10 tin cũ dần nên phải sắp xếp giảm dần

DECLARE @ID INT
DECLARE cs_newID CURSOR
FOR Select newID from NEWS Order by timeNews desc
OPEN cs_newID
FETCH NEXT FROM cs_newID INTO @ID
WHILE(@@FETCH_STATUS=0)
BEGIN
if(@newID = @ID)
Begin
Select top 10 newID,col1,... from #Temp Order by timeNews desc
break
End
else
Begin
Delete from #Temp where newID = @ID
FETCH NEXT FROM cs_newID INTO @ID
End
END
CLOSE cs_newID
DEALLOCATE cs_newID
End

exec sp_OutTop10 'N001323' ---Ví dụ một newID

P/S: Có gì không đúng nữa bạn tác giả đừng bùn nhen.
Reply With Quote
  #10  
Old 06-07-2009, 02:15
Registered User
 
Tham gia: 01-04-2009
Bài viết: 66
Hấp dẫn đây ! Phân trang khi lấy dữ liệu

Có cần nhiều cách không, một cách là đủ rồi.

cách thứ hai chưa tốt khi mở rộng n --> 3 .. 30 phần, bạn viết " lun hen ", dài lắm cho 30 câu lồng nhau.
cách thứ ba thì hỏng, tham số là int mà lại " thử roài " bằng string.

Bạn cũng nên biết trong ms sql srv , cursor không được tối ưu về tốc độ mà lại cho quét hết ( từ đầu đến cuối bảng ) thì bao giờ lấy được kết quả.

Trong vài trường hợp cursor có ưu thế, trong ví dụ này, có tốc độ hơn những cách khác với nBase đủ lớn.

************************************************Bs sssssssssssssN******
từ vị trí cần lấy nBase, tuần tự lấy ra nRow cho một trang
/* tham khảo kỹ thuật phân trang khi lấy dữ liệu từ DB */

create proc sp_GetPageWithCursor @nBase int, @nRow int = 10 AS Begin
if @nBase < 0 or @nRow < 1 return -1
if (select count(*) FROM ...) <= @nBase return -2
set noCount on
create table #Temp( lstCols lstDataTypes )
-- Select newID,col1,... into #Temp from NEWS Order by timeNews desc
DECLARE @dem int, @lstVals lstUddts

select @dem= 0, @nBase= @nBase + 1 --Syntax for ABSOLUTE @Var
DECLARE C_cursor CURSOR SCROLL READ_ONLY FOR
SELECT lstCols from ..
OPEN C_cursor
-- FETCH NEXT FROM C_cursor
FETCH ABSOLUTE @nBase FROM C_cursor into @lstVals
IF @@FETCH_STATUS <> 0 GOTO eRows
WHILE @@FETCH_STATUS = 0 and @dem < @nRow BEGIN
set @dem= @dem + 1
insert #Temp ( lstCols ) values ( @lstVals )
--
FETCH NEXT FROM C_cursor into @lstVals
END

eRows:
CLOSE C_cursor
DEALLOCATE C_cursor
--
select * from #Temp
--return @dem
End
go

exec sp_GetPageWithCursor 50000, 20
--exec sp_GetPageWithCursor 50000

Xin đừng " bùn nhen ", ....

Được sửa bởi Van8Hien62 lúc 14:24 ngày 06-07-2009. Reason: Copy and Paste, chưa cẩn thận

0 nhận xét:

Đăng nhận xét