En a obtenu une tâche de programmation dans le domaine de T-SQL
.
Tâche:
- Les gens veulent entrer dans un ascenseur, chaque personne a un certain poids.
- L'ordre des personnes faisant la queue est déterminé par le tour de colonne.
- L'ascenseur a une capacité maximale de <= 1000 lb.
- Retournez le nom de la dernière personne qui peut entrer dans l'ascenseur avant qu'il ne soit trop lourd!
- Le type de retour doit être une table
Question: Quelle est la façon la plus efficace de résoudre ce problème? Si le bouclage est correct, y a-t-il place à amélioration?
J'ai utilisé une boucle et des tables # temp, voici ma solution:
set rowcount 0
-- THE SOURCE TABLE "LINE" HAS THE SAME SCHEMA AS #RESULT AND #TEMP
use Northwind
go
declare @sum int
declare @curr int
set @sum = 0
declare @id int
IF OBJECT_ID('tempdb..#temp','u') IS NOT NULL
DROP TABLE #temp
IF OBJECT_ID('tempdb..#result','u') IS NOT NULL
DROP TABLE #result
create table #result(
id int not null,
[name] varchar(255) not null,
weight int not null,
turn int not null
)
create table #temp(
id int not null,
[name] varchar(255) not null,
weight int not null,
turn int not null
)
INSERT into #temp SELECT * FROM line order by turn
WHILE EXISTS (SELECT 1 FROM #temp)
BEGIN
-- Get the top record
SELECT TOP 1 @curr = r.weight FROM #temp r order by turn
SELECT TOP 1 @id = r.id FROM #temp r order by turn
--print @curr
print @sum
IF(@sum + @curr <= 1000)
BEGIN
print 'entering........ again'
--print @curr
set @sum = @sum + @curr
--print @sum
INSERT INTO #result SELECT * FROM #temp where [id] = @id --id, [name], turn
DELETE FROM #temp WHERE id = @id
END
ELSE
BEGIN
print 'breaaaking.-----'
BREAK
END
END
SELECT TOP 1 [name] FROM #result r order by r.turn desc
Voici le script de création pour la table que j'ai utilisée Northwind pour les tests:
USE [Northwind]
GO
/****** Object: Table [dbo].[line] Script Date: 28.05.2018 21:56:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[line](
[id] [int] NOT NULL,
[name] [varchar](255) NOT NULL,
[weight] [int] NOT NULL,
[turn] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED
(
[turn] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[line] WITH CHECK ADD CHECK (([weight]>(0)))
GO
INSERT INTO [dbo].[line]
([id], [name], [weight], [turn])
VALUES
(5, 'gary', 800, 1),
(3, 'jo', 350, 2),
(6, 'thomas', 400, 3),
(2, 'will', 200, 4),
(4, 'mark', 175, 5),
(1, 'james', 100, 6)
;
Client statistics --> Total Execution Time
, pas celuiActual execution plan
qui est probablement le plus intéressant ici. A partir deClient Statistics
votre solution est un petit peu plus lent que Martin. Merci pour l'information supplémentaire. Quelle méthode peut-on utiliser pour mesurer les différences de performances entre différentes approches?