2016-04-05 22 views
2

Yineleme sayısı alanı olan bir tablo yerine her ay için bir kayıt içeren bir tabloya ihtiyacım var.Yinelenen kayıtları göstermek için şu anda bir alanı olan bir tabloyu "genişletmek" için bir sql sorgusu nasıl yazarım?

Property  Item  Month   Repeat_Count  Amount 
------------------------------------------------------------------ 
A    Rent  1/1/2016  1    100 
A    Rent  2/1/2016  1    105 
A    Rent  3/1/2016  3    110 
A    Rent  6/1/2016  1    115 
A    Rent  7/1/2016  6    120 
A    Rent  1/1/2017  1    125 

Ve böyle bakmak istiyorum:

Benim verileri şu anda şöyle görünür

Property Item  Month   Amount 
----------------------------------------- 
A   Rent  1/1/2016  100 
A   Rent  2/1/2016  105 
A   Rent  3/1/2016  110 
A   Rent  4/1/2016  110 
A   Rent  5/1/2016  110 
A   Rent  6/1/2016  115 
A   Rent  7/1/2016  120 
A   Rent  8/1/2016  120 
A   Rent  9/1/2016  120 
A   Rent  10/1/2016  120 
A   Rent  11/1/2016  120 
A   Rent  12/1/2016  120 
A   Rent  1/1/2017  125 

Umut, teşekkürler bu bir açıklayan iyi bir iş yaptı!

+1

Lütfen sorunuzu kullandığınız veritabanı ile etiketleyin. En iyi yol veritabanına bağlıdır. –

+1

Merhaba ve taşma yığınına hoş geldiniz. Burada ilk önce kendinize gitmenizi bekliyoruz ... en azından işe yarayacak fikirleri araştırmak için ... sonra ne denediğinizi bize gösterin. –

+0

Sanırım bu benim sorunum - SQL deneyimim var, fakat basit sorgulamalar ve katılımlar ile - hiç böyle bir şeye rastlamamıştım, bu yüzden verileri tamamen farklı bir şekilde göstermem gerekiyor. Araştırmaya çalışmam gereken belirli bir komut var mı? –

cevap

2

table of numbers ve CROSS APPLY kullanırdım.

Sayı tablosu, 1'den tam sayıya kadar bir sayıya, 100.000'e kadar bir tamsayı sayıları olan bir sütuna sahip bir tablodur. Şahsen 100K numaraları ile tabloyu kullanıyorum. Aaron Bertrand, bu tabloyu nasıl oluşturacağınızı açıklayan bir good article yazdı.

Örnek veri

DECLARE @T TABLE ([Property] varchar(50), [Item] varchar(50), [Month] datetime, [Repeat_Count] int, [Amount] int); 

INSERT INTO @T ([Property], [Item], [Month], [Repeat_Count], [Amount]) VALUES 
('A', 'Rent', '2016-01-01 00:00:00', 1, 100), 
('A', 'Rent', '2016-02-01 00:00:00', 1, 105), 
('A', 'Rent', '2016-03-01 00:00:00', 3, 110), 
('A', 'Rent', '2016-06-01 00:00:00', 1, 115), 
('A', 'Rent', '2016-07-01 00:00:00', 6, 120), 
('A', 'Rent', '2017-01-01 00:00:00', 1, 125); 

Sorgu

SELECT * 
FROM 
    @T AS T 
    CROSS APPLY 
    (
     SELECT 
      DATEADD(day, dbo.Numbers.Number-1, T.Month) AS NewDate 
     FROM dbo.Numbers 
     WHERE dbo.Numbers.Number <= T.Repeat_Count 
    ) AS CA 
ORDER BY NewDate; 

Sonucu

+----------+------+-------------------------+--------------+--------+-------------------------+ 
| Property | Item |   Month   | Repeat_Count | Amount |   NewDate   | 
+----------+------+-------------------------+--------------+--------+-------------------------+ 
| A  | Rent | 2016-01-01 00:00:00.000 |   1 | 100 | 2016-01-01 00:00:00.000 | 
| A  | Rent | 2016-02-01 00:00:00.000 |   1 | 105 | 2016-02-01 00:00:00.000 | 
| A  | Rent | 2016-03-01 00:00:00.000 |   3 | 110 | 2016-03-01 00:00:00.000 | 
| A  | Rent | 2016-03-01 00:00:00.000 |   3 | 110 | 2016-03-02 00:00:00.000 | 
| A  | Rent | 2016-03-01 00:00:00.000 |   3 | 110 | 2016-03-03 00:00:00.000 | 
| A  | Rent | 2016-06-01 00:00:00.000 |   1 | 115 | 2016-06-01 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-01 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-02 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-03 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-04 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-05 00:00:00.000 | 
| A  | Rent | 2016-07-01 00:00:00.000 |   6 | 120 | 2016-07-06 00:00:00.000 | 
| A  | Rent | 2017-01-01 00:00:00.000 |   1 | 125 | 2017-01-01 00:00:00.000 | 
+----------+------+-------------------------+--------------+--------+-------------------------+ 
+0

Bunu yaptı, teşekkürler! –

1

Birkullanabilirsiniztarihlerini oluşturmak için:

WITH E1(N) AS(-- 10^1 = 10 rows 
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N) 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10^2 = 100 rows 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10^4 = 10,000 rows 
CteTally(N) AS(
    SELECT TOP(SELECT MAX(Repeat_Count) FROM tbl) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) 
    FROM E4 
) 
SELECT 
    t.Property, 
    t.Item, 
    [Month] = DATEADD(MONTH, c.N-1, t.Month), 
    t.Amount 
FROM tbl t 
INNER JOIN CteTally c 
    ON c.N <= t.Repeat_Count 
ORDER BY t.Property, t.Item, [Month] 
İlgili konular