假设我有一个客户列表,我想将它们分配给总线。我有John,Ringo,Paul .....他们可以乘坐粉红色或绿色巴士。我们的想法是分配
John: Pink
Ringo: Green
Paul: Pink
有没有人知道如何在不诉诸循环声明的情况下做到这一点?
--DROP TABLE [BusAllocation]
CREATE TABLE [dbo].[BusAllocation]
(
[ClientName] [varchar](50) NOT NULL,
[BusAllocation] [varchar](50) NULL
);
INSERT INTO BusAllocation([ClientName]) VALUES('John');
INSERT INTO BusAllocation([ClientName]) VALUES('Ringo');
INSERT INTO BusAllocation([ClientName]) VALUES('Paul');
INSERT INTO BusAllocation([ClientName]) VALUES('Simon');
INSERT INTO BusAllocation([ClientName]) VALUES('Tyrone');
CREATE TABLE [dbo].[Bus]
(
BusName [varchar](50) NOT NULL,
);
INSERT INTO [Bus](BusName) VALUES('Pink');
INSERT INTO BusAllocation([ClientName]) VALUES('Green');
答案 0 :(得分:1)
我们大多数人为什么不使用Id列令人困惑。但是,如果它就像你说的那么简单,这将是实现你想要的最小代码。
DECLARE @RowIndex int = 0
UPDATE BusAllocation
SET BusAllocation = CASE WHEN @RowIndex % 2 = 0 THEN 'Pink' ELSE 'Green' END,
@RowIndex = @RowIndex + 1
我怀疑当你进入下一步时,你将意识到身份列的价值,并在每个表上放置一个。然后会有一个Client表,Bus表和BusAllocation表。 BusAllocation表将具有ClientId和BusId列,这就是您将总线分配给客户端的方式。
答案 1 :(得分:0)
我假设您希望将客户交替分配给粉红色然后是绿色公共汽车 - 这不是您的问题所在。
您可以将自动递增列添加到Client表,然后使用带有更新语句的模块除2吗?
Client表格如下:
CREATE TABLE Client (
ClientId INT IDENTITY(1,1) NOT NULL,
ClientName varchar(50) NOT NULL
)
第一个更新语句如下所示:
UPDATE BusAllocation
SET BusAllocation = 'Green'
WHERE ClientName IN (SELECT ClientName FROM Client WHERE ClientID % 2 = 0)
第二个更新声明同样是UPDATE BusAllocation SET BusAllocation = 'Pink' WHERE ClientName IN (SELECT ClientName FROM Client WHERE ClientId % 2 = 1)
如果您想要非常严格,您可能希望避免将此选择列作为PK - 只需添加一个辅助列。
答案 2 :(得分:0)
以下代码演示了基本技术。希望真正的表格有一些独特的字段,可用于提供代替( order by ( select NULL ) )
黑客的订单。
请注意,代码会为每行生成数字,而与其他任何数据无关。它不会因身份价值的差距而绊倒,例如:删除行或回滚事务时。
-- Sample data.
declare @BusAllocation as Table ( ClientName VarChar(10), BusAllocation VarChar(10) );
insert into @BusAllocation values
( 'John', NULL ), ( 'Ringo', NULL ), ( 'Paul', NULL ), ( 'Simon', NULL ), ( 'Tyrone', NULL );
select * from @BusAllocation;
declare @Bus as Table ( BusName VarChar(10) );
insert into @Bus values
( 'Pink' ), ( 'Green' );
select * from @Bus;
-- Mix and match the buses and output the result.
with
NumberedBuses as (
select BusName, Row_Number() over ( order by ( select NULL ) ) - 1 as RN
from @Bus ),
NumberedClients as (
select ClientName, Row_Number() over ( order by ( select NULL ) ) - 1 as RN
from @BusAllocation )
select NC.RN, ClientName, BusName
from NumberedClients as NC inner join
NumberedBuses as NB on NB.RN = NC.RN % ( select count(42) from NumberedBuses )
order by NC.RN;
-- Do it again updating the table.
with
NumberedBuses as (
select BusName, Row_Number() over ( order by ( select NULL ) ) - 1 as RN
from @Bus ),
NumberedClients as (
select ClientName, Row_Number() over ( order by ( select NULL ) ) - 1 as RN
from @BusAllocation )
update @BusAllocation
set BusAllocation = NB.BusName
from @BusAllocation as BA inner join
NumberedClients as NC on NC.ClientName = BA.ClientName inner join
NumberedBuses as NB on NB.RN = NC.RN % ( select count(42) from NumberedBuses );
select * from @BusAllocation;