我需要为选定的重复值添加字符/数字。
这就是我需要的:
SELECT Name -- Here I need to add for example 1 if It have duplicates
-- If It is hard way to code, how to add 1 to all selected values?
FROM Example
WHERE Id BETWEEN 25 AND 285
如果有2个相同的名称Peter
则应选择Peter
和第二个Peter1
如果没有简单的方法来制作它,如何将1
添加到所有选定的行?应选择Peter1
而不是Peter
我试过这个:
SELECT Name + ' 1' AS Name -- in this case selecting wrong column
FROM Example
WHERE Id BETWEEN 25 AND 285
修改
SELECT @cols += ([Name]) + ','
FROM (SELECT Name --I neeed to integrate It here
FROM FormFields
WHERE ID BETWEEN 50 AND 82
) a
如果我使用它:
SELECT @cols += ([Name]) + ',' -- here throws error
FROM (SELECT Name + CASE WHEN RowNum = 1 THEN '' ELSE CONVERT(NVARCHAR(100), RowNum-1) END AS [UpdatedName]
FROM (
SELECT Name AS Name,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Name) AS "RowNum"
FROM FormFields
WHERE Id Between 50 And 82) x
) a
抛出错误:Invalid column name 'Name'.
编辑2
它的测试不同,但其中一些测试标准相同。这就是我需要重命名的原因。
答案 0 :(得分:5)
您可以通过Row_Number
并使用Case
来完成此操作。以下是SQL Server
的示例:
;With Cte As
(
Select Name, Row_Number() Over (Partition By Name Order By Name) RN
From Example
Where Id Between 25 And 285
)
Select Case When RN = 1 Then Name Else Name + Cast((RN - 1) As Varchar (3)) End As Name
From Cte
答案 1 :(得分:1)
您可以使用SQL Server中内置的ROW_NUMBER函数。
select Name + case when RowNum = 1 then '' else CONVERT(varchar(100), RowNum-1) end as "UpdatedName"
from (
select name as "Name",
ROW_NUMBER() over (partition by name order by name) as "RowNum"
from Example
Where Id Between 25 And 285) x
请注意,这仍然不能保证您的名字。毕竟,有人可能已经有了#34; MyName1"的名字,所以如果你有2个人的名字" MyName"你还得到2" MyName1"用这个select语句。
答案 2 :(得分:1)
这是一个非常不寻常的要求,看起来你正试图让汽车在车顶上用轮子行驶" :)
根本问题几乎肯定是错误的数据库设计...... Pivot通常用于数据摘要。如果你在同一列中,彼得"和彼得"它具有不同的含义,看起来有些不对劲。或者您是否因任何其他原因需要区分彼得斯?
我不明白你想要达到的目标。如果彼得总是彼得,并且你只是想避免重复,你可以简单地使用"按名称分组"。但这就是枢轴自动完成的......如果彼得和彼得有两种不同的含义(如Peter1和Peter2),你应该考虑改变数据库结构,如果可能的话。
或者尝试更深入地解释你想要实现的目标。
编辑:
好的,现在我理解了所需的输出。您的源数据表的结构是什么?从您的架构中可以看出,您需要根据
创建PIVOT列Testname+groupId
或
Testname+convert(varchar(100),groupId)
如果groupId是数字。那是你的Peter1,Peter2的组合。它将创建您需要的列。但我不知道testname和groupId在数据表中的位置。测试名称是否与列NAMES或存储在DB中的VALUES相对应? groupId有类似TestId吗?列还是值?提供有关源数据结构的更多信息,如果您需要更多帮助,您的问题就不那么复杂了。
答案 3 :(得分:1)
由于列具有组ID,因此将列名称与Underscore和GroupID连接为键值,并在显示时删除下划线和尾随字符。
喜欢这个:
SELECT @cols += ([Name]) + ','
FROM (SELECT Name + '_' + CAST(GroupId AS varchar)
FROM FormFields
WHERE ID BETWEEN 50 AND 82
) a
我假设您正在使用它来构建动态SQL语句。我不确定FormFields表的模式是什么,但如果它包含类似测试名称的内容,您可以附加AS [Name] +' - '+ [TestName]以使列标题更有用。我会说尝试PIVOT,但如果测试没有大多数共同的领域,那可能会非常笨拙......
我还假设您在这些提示中存储对这些提示的响应,如下所示:
CREATE TABLE [Responses]
(
RespID int IDENTITY NOT NULL,
UserID int NOT NULL,
FieldID int NOT NULL,
RespVal int/varchar/whatever NOT NULL
)
然后,您可能有一个[Test]表,其中包含一些测试元数据,这些元数据充当FormFields表中GroupID外键的主键。
在您的示例中,您显示了所有列的回复,但我不确定这是如何工作的(除非我在您的解释中遗漏了一些内容以及我对您的设计做出的推断)一组回复只能为每行的一个组填充,除非您要汇总响应,但是按照什么标准?行可能与受访者相对应,所有受访者都需要回答所有表单类型。在这种情况下,您的输出将像这样的PIVOT:
DECLARE @sql varchar(4000) = ''
DECLARE @colList varchar(1000)
DECLARE @selList varchar(1000)
;WITH NameBase
AS
(
SELECT t.Name [TestName], f.Name [FieldName], f.GroupId
FROM [FormFields] f
INNER JOIN [Tests] t ON f.GroupID = t.ID
)
SELECT @colList = COALESCE(@colList + ',','') + QUOTENAME([FieldName] + '_' + [GroupId])
, @selList = COALESCE(@selList + ',','') + QUOTENAME([FieldName] + '_' + [GroupId]) + ' AS ' + QUOTENAME([FieldName] + ' - ' + [TestName])
FROM NameBase
SELECT @sql = 'SELECT [UserName],' + @selList + ' FROM (
SELECT u.Name [UserName], f.Name + '_' + f.GroupId [FieldName], r.RespVal [Response]
FROM Responses r
INNER JOIN [TestUsers] u ON r.UserID = u.ID
INNER JOIN [FormFields] f ON r.FieldID = f.ID) t
PIVOT (MAX([Response]) FOR [FieldName] IN (' + @colList + ')) pvt'
EXECUTE(@sql);
我还没有测试过,但它至少应该指向正确的方向。我将尝试构建一个SqlFiddle以稍微测试它。