2010-07-09 14 views
9

Tôi có truy vấn tôi đang làm việc và tôi muốn tăng một trong các trường và khởi động lại bộ đếm khi giá trị khóa khác nhau.Cách tăng trong truy vấn chọn

Tôi biết mã này không hoạt động. Lập trình này là những gì tôi muốn ...

declare @counter int, @id 
set @counter = 0 
set @id = 0 

select distinct 
    id, 
    counter = when id = @id 
       then @counter += 1 
      else @id = id 
       @counter = 1  

... với kết quả cuối cùng tìm kiếm một cái gì đó như thế này:

ID Counter 
3  1 
3  2 
3  3 
3  4 
6  1 
6  2 
6  3 
7  1 

Và vâng, tôi đang mắc kẹt với SQL2k. Nếu không thì row_number() sẽ hoạt động.

+0

Tùy thuộc vào phần còn lại của những gì có sẵn trong truy vấn của bạn, có lẽ Row_Number() sẽ giúp ích gì? – reallyJim

+0

@reallyJim: Nếu họ đang sử dụng SQL2K, như các thẻ đề xuất, thì 'ROW_NUMBER' sẽ không khả dụng. – LukeH

+0

@LukeH TOTALLY đã bỏ lỡ điểm đó! – reallyJim

Trả lời

12

Giả sử một bảng:

CREATE TABLE [SomeTable] (
    [id] INTEGER, 
    [order] INTEGER, 
    PRIMARY KEY ([id], [order]) 
); 

Một cách để có được điều này trong Microsoft SQL Server 2000 là sử dụng một subquery để đếm các hàng với cùng id và một thứ tự thấp hơn.

SELECT *, (SELECT COUNT(*) FROM [SomeTable] counter 
      WHERE t.id = counter.id AND t.order < counter.order) AS row_num 
FROM [SomeTable] t 

Mẹo: Đó là năm 2010. Không lâu SQL Server của bạn sẽ đủ tuổi để lái xe.

Nếu bạn sử dụng SQL Server 2005 trở lên, bạn sẽ có được các chức năng mới tuyệt vời như ROW_NUMBER() OVER (PARTITION...).

+5

SQL 2000 vẫn vui. Tại 13+, SQL Server 7.0 là sullen hầu hết thời gian và chơi trò chơi video cả ngày. –

+4

Chúng tôi đang thực sự làm việc trên chiếc xe đầu tiên của SQL2k. Nếu anh ta giữ cho mũi mình sạch sẽ và đạt điểm tốt, đó sẽ là món quà sinh nhật 16 tuổi của anh ấy. ; o) – Mikecancook

+3

Chúng lớn lên rất nhanh! * sniff * –

6

Có bạn muốn ROW_NUMBER().

tôi sẽ cố gắng:

SELECT id, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS Counter 
+0

Không thể - SQL Server không hỗ trợ chức năng phân tích/xếp hạng/cửa sổ cho đến khi v2005 –

1

Có row_number() có nghĩa là bạn phải đối phó với các truy vấn phụ xa hơn, ít liên quan hơn nhiều. Giải pháp @Bill Karwin hoạt động (+1); đây là một phiên bản khác làm điều tương tự nhưng có thể dễ dàng hơn một chút để làm theo. (Tôi đã từng datetimes để xác định đặt hàng.)

-- Test table 
CREATE TABLE Test 
(Id  int  not null 
    ,Loaded datetime not null 
) 

-- Load dummy data with made-up distinct datetimes 
INSERT Test values (3, 'Jan 1, 2010') 
INSERT Test values (3, 'Jan 2, 2010') 
INSERT Test values (3, 'Jan 5, 2010') 
INSERT Test values (3, 'Jan 7, 2010') 
INSERT Test values (6, 'Feb 1, 2010') 
INSERT Test values (6, 'Feb 11, 2010') 
INSERT Test values (7, 'Mar 31, 2010') 


-- The query 
SELECT t1.Id, count(*) Counter 
from Test t1 
    inner join Test t2 
    on t2.Id = t1.Id 
    and t2.Loaded <= t1.Loaded 
group by t1.Id, t1.Loaded 


-- Clean up when done 
DROP TABLE Test 

Điều quan trọng cần lưu ý là, không chỉ số tốt (và có lẽ ngay cả với họ), các loại truy vấn có thể thực hiện rất kém, đặc biệt là trên các bảng lớn. Kiểm tra và tối ưu hóa cẩn thận!

3

Một cách để làm điều này là đưa dữ liệu vào bảng tạm thời với cột nhận dạng được sử dụng làm số hàng. Sau đó làm cho cột truy cập một số các hàng khác với cùng một ID và một số hàng thấp + 1.

CREATE TABLE #MyData(
Id INT 
); 

INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(3); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(6); 
INSERT INTO #MyData VALUES(7); 

CREATE TABLE #MyTempTable(
RowNum INT IDENTITY(1,1), 
Id INT, 
Counter INT 
); 

INSERT INTO #MyTempTable 
SELECT Id, 0 
FROM #MyData 
ORDER BY Id; 

SELECT Id, (SELECT COUNT(*) + 1 FROM #MyTempTable WHERE Id = t1.Id AND RowNum < t1.RowNum) AS 'Counter' 
FROM #MyTempTable t1; 

Bạn sẽ nhận được đầu ra sau đây dựa trên ví dụ của bạn:

Id Counter 
3 1 
3 2 
3 3 
3 4 
6 1 
6 2 
6 3 
7 1