我有一组记录,其中包含"商店"列.我需要基本上将结果集拆分为13个记录的组,创建空行以填充每个商店以包含13行.为简单起见,我想说我需要4组记录.
示例,给出下表:
-----------------
Store Name
-----------------
A John
A Bill
B Sam
C James
C Tim
C Chris
D Simon
D Phil
Run Code Online (Sandbox Code Playgroud)
我需要结果看起来像:
-----------------
Store Name
-----------------
A John
A Bill
A
B Sam
B
B
C James
C Tim
C Chris
D Simon
D Phil
D
Run Code Online (Sandbox Code Playgroud)
纯SQL是否可以实现这一点?每个商店永远不会超过3行. SQL小提琴
试试这个 -
DDL:
SET STATISTICS IO ON;
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
Store CHAR(1)
, Name VARCHAR(10)
)
INSERT INTO #temp (Store, Name)
VALUES
('A', 'John'), ('A', 'Bill'),
('B', 'Sam'), ('C', 'James'),
('C', 'Tim'), ('C', 'Chris'),
('D', 'Simon'), ('D', 'Phil')
Run Code Online (Sandbox Code Playgroud)
查询:
DevArt#1:
;WITH cte AS
(
SELECT
Store
, Name
, rn = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY (SELECT 1))
FROM #temp
)
SELECT t.Store, Name = ISNULL(t3.Name, '')
FROM (
SELECT DISTINCT Store
FROM cte
) t
CROSS JOIN (SELECT rn = 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t2
LEFT JOIN cte t3 ON t2.rn = t3.rn AND t.Store = t3.Store
Run Code Online (Sandbox Code Playgroud)
DevArt#2:
SELECT t2.Store, Name = ISNULL(t3.Name, '')
FROM (
SELECT *
FROM (
SELECT Store, r = COUNT(1)
FROM #temp
GROUP BY Store
) t
CROSS APPLY (
VALUES (r), (r+1), (r+2)
) t2 (x)
) t2
LEFT JOIN #temp t3 ON t2.Store = t3.Store AND t2.x = t2.r
WHERE t2.x < 4
Run Code Online (Sandbox Code Playgroud)
Alexander Fedorenko:
;WITH cte AS
(
SELECT DISTINCT Store
FROM #temp
)
SELECT o.Store, o.name
FROM cte s
CROSS APPLY (
SELECT TOP 3 x.Store, x.name
FROM (
SELECT s2.Store, s2.name
FROM #temp s2
WHERE s.Store = s2.Store
UNION ALL
SELECT s.Store, ''
UNION ALL
SELECT s.Store, ''
) x
) o
Run Code Online (Sandbox Code Playgroud)
ErikE:
SELECT Store, Name
FROM (
SELECT
x.Store
, x.Name
, s = ROW_NUMBER() OVER (PARTITION BY x.Store ORDER BY x.s)
FROM #temp t
CROSS APPLY (
VALUES
(Store, Name, 0),
(Store, '', 1),
(Store, '', 1)
) x (Store, Name, S)
) z
WHERE s <= 3
ORDER BY Store
Run Code Online (Sandbox Code Playgroud)
AmitSingh:
SELECT t.Store, Name = COALESCE(
(
SELECT name
FROM (
SELECT
row1 = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY Store)
, *
FROM #temp
) c
WHERE t.[row] = c.row1
AND t.Store = c.Store
)
, '')
FROM
(
SELECT
[Row] = ROW_NUMBER() OVER (PARTITION BY a.Store ORDER BY a.Store)
, a.Store
FROM (
SELECT Store
FROM #temp
GROUP BY Store
) a
, (
SELECT TOP 3 Store
FROM #temp
) b
) t
Run Code Online (Sandbox Code Playgroud)
Andriy M#1:
;WITH ranked AS
(
SELECT
Store
, Name
, rnk = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY 1/0)
FROM #temp
)
, pivoted AS
(
SELECT
Store
, [1] = ISNULL([1], '')
, [2] = ISNULL([2], '')
, [3] = ISNULL([3], '')
FROM ranked
PIVOT (
MAX(Name)
FOR rnk IN ([1], [2], [3])
) p
)
, unpivoted AS
(
SELECT
Store
, Name
FROM pivoted
UNPIVOT (
Name FOR rnk IN ([1], [2], [3])
) u
)
SELECT *
FROM unpivoted
Run Code Online (Sandbox Code Playgroud)
Andriy M#2:
;WITH ranked AS
(
SELECT
Store
, Name
, rnk = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY 1/0)
FROM #temp
)
, padded AS
(
SELECT
Store
, Name
FROM ranked
PIVOT (
MAX(Name)
FOR rnk IN ([1], [2], [3])
) p
CROSS APPLY (
VALUES
(ISNULL([1], '')),
(ISNULL([2], '')),
(ISNULL([3], ''))
) x (Name)
)
SELECT *
FROM padded
Run Code Online (Sandbox Code Playgroud)
输出:
Store Name
----- ----------
A John
A Bill
A
B Sam
B
B
C James
C Tim
C Chris
D Simon
D Phil
D
Run Code Online (Sandbox Code Playgroud)
统计:
Query Presenter Scans Logical Reads
------------------- ----- -------------
DevArt #1 3 41
DevArt #2 2 9
Alexander Fedorenko 4 5
ErikE 1 1
AmitSingh 22 25
Andriy M #1 1 1
Andriy M #2 1 1
Run Code Online (Sandbox Code Playgroud)
查询费用:

扩展统计:

执行统计:

查询计划(来自dbForge Studio for MS SQL):
