2012-04-30 31 views
5

Tôi có một bảng SQL Server AccountAction được chuẩn hóa. Đây là phiên bản được làm phẳng của các bảng AccountAction mà tôi hy vọng sẽ nhanh hơn rất nhiều cho các truy vấn báo cáo qua hàng triệu hàng. Một Account có thể có nhiều Actions, vì vậy bảng trông tương tự như:SQL để lấy số lượng tài khoản X từ DB, có thể là số lượng các hàng khác nhau

Account  Action 
account1 action1 
account1 action2 
account1 action10 
account2 action5 

Tuy nhiên tôi đang gặp một số sự cố khi nhận thông tin trở lại cho một tập hợp con bị hạn chế trong một thủ tục lưu trữ đơn giản.

select Account, Action 
from AccountAction 
where ??? 

Điều tôi đang tìm kiếm là nhận được các tài khoản X đầu tiên, với tất cả các hành động của chúng. Vì vậy, đây sẽ là số hàng động. Vì vậy, bằng cách sử dụng bảng ví dụ ở trên nếu tôi chuyển vào 1, tôi sẽ nhận được 3 hàng (ví dụ: cung cấp cho tôi tất cả các hàng cho tài khoản đầu tiên).

(Tôi không nhớ rằng tên tài khoản sẽ được trong mỗi hàng - đó là xoay những nơi khác)

Tôi có cần phải sử dụng một ROWNUM hoặc tương tự để hạn chế các hàng? Tôi chắc chắn đây phải là một vấn đề đơn giản hơn tôi đã tìm thấy cho đến nay.

EDIT

Những câu trả lời bằng TOP sẽ không hoạt động, trong ví dụ tôi muốn được muốn 3 hàng trả lại nếu tôi nói 'cho tôi một (đầu tiên) tài khoản'. Nhưng làm thế nào để tôi biết sẽ có 3? Năng động của nó. Ngoài ra, chúng có thể không được tuần tự, điều gì sẽ xảy ra nếu action1 của account1 ở vị trí 55 triệu trong kết quả.

Trả lời

4
WITH 
    SequencedData 
AS 
(
    SELECT 
    DENSE_RANK() OVER (ORDER BY Account) AS account_sequence_id, 
    * 
    FROM 
    AccountAction 
) 
SELECT 
    * 
FROM 
    SequenceData 
WHERE 
    account_sequence_id = ??? 

Hoặc, đối với bội số ...

WHERE 
    account_sequence_id BETWEEN 3 AND 5 -- For the 3rd, 4th and 5th accounts. 
+0

Điều này nghe có vẻ hay, mặc dù về hiệu suất trên ví dụ 100m hàng? Nó sẽ phải làm xếp hạng trên mỗi hàng đầu tiên phải không? – finoutlook

+1

@finoutlook - Tùy theo. Tất cả những gì * thực sự * cần thiết là có dữ liệu trong thứ tự 'Tài khoản'. Khi được yêu cầu, người tối ưu hóa chỉ có thể tìm kiếm thể hiện của 'Nth'. Vậy, bạn đã có chỉ mục với 'Tài khoản' là trường đầu tiên chưa? Nếu vậy, dữ liệu đã được đặt hàng và bạn chỉ xử lý số lượng bản ghi tối thiểu. Nếu không, hãy thêm một;) – MatBailie

+0

Thật tuyệt, tôi đã không nghĩ đến việc sắp đặt trước chúng. Tôi có thể làm điều đó như một phần của đồng bộ hóa với bảng không chuẩn hóa. – finoutlook

0

Nếu tôi nhận được câu hỏi đúng sau đó nếu u muốn chọn ban đầu 10 dòng sau đó sử dụng

SELECT TOP 10 Account, Action 
FROM AccountAction 

hoặc nếu u muốn khoảng 20 hồ sơ trăm ban đầu sau đó use-

SELECT TOP 10 PERCENT Account, Action 
FROM AccountAction 
+0

Các OP muốn 'cái tài khoản Nth', trong đó mỗi tài khoản có thể có một số lượng khác nhau của ghi lại mỗi. – MatBailie

0

bạn đã thử TOP?

declare @hoW_many int 
set @hoW_many = 10 

select top (@hoW_many) * 
from AccountAction 
+0

OP không muốn 'hàng N đầu tiên', OP muốn' Tài khoản Nth', trong đó mỗi tài khoản có một số hàng khác nhau. – MatBailie

1
SELECT * 
FROM AccountAction 
WHERE account IN (SELECT account 
    FROM AccountAction 
    GROUP BY account HAVING account BETWEEN *start-account* AND *end-account* 
    ORDER BY account 
) 

Giải thích: Các nhóm subquery bằng các tài khoản riêng biệt (và cho phép tiêu chí lựa chọn nhiều hạt mịn hơn một đơn giản DISTINCT) và chỉ trả về các tài khoản. SELECT bên ngoài mang lại cho bạn một số lượng hàng thay đổi tùy thuộc vào các tài khoản riêng biệt được tìm nạp bởi truy vấn phụ.

EDIT: Ở trên giả định rằng người ta có thể lọc theo trường account trong bảng AccountAction; điều này thường xảy ra trong các bảng mà tham gia mối quan hệ M:N ở cấp DB.

+2

'LIMIT' không phải là hàm SQL-Server. – GarethD

+0

@GarethD Cảm ơn đã cập nhật mã của tôi để sử dụng 'TOP' thay vào đó, với cùng tác dụng của' LIMIT' trước đây. –

+0

Đăng thay đổi từ LIMIT thành TOP - Còn nếu OP cần thứ 3, thứ 4 và thứ 5 thì sao? Tôi cũng sẽ +1 khi bạn thực hiện thay đổi đó :) – MatBailie

0

Một đơn giản phụ chọn với top từ khóa (và khác biệt), sẽ cung cấp cho bạn tất cả các hành động cho đầu X chiếm

select * from AccountAction 
where Account in 
(select distinct top (@NumberOfAccounts) Account 
from AccountAction order by Account) 
+1

Bạn cần một ORDER BY trong truy vấn phụ khác kết quả có thể khác nhau từ thực thi đến thực thi. Sau đó, nó giống như câu trả lời của JosvicZammit, từ 6 phút trước khi bạn * (Nơi DISTINCT và GROUP BY có thể hoán đổi cho nhau) *. – MatBailie

+0

@Dems - Trả lời sửa đổi để bao gồm ORDER BY; nhưng ý định của tôi không bao gồm câu trả lời trùng lặp ... –

Các vấn đề liên quan