很抱歉,标题不好,我想不出更好的办法。随时编辑。
我必须使用一个数据库表,该数据库表使用一列来存储不同类型的信息(如果是个人,则为姓,如果是公司,则为公司名)。我知道是一场噩梦,但事实就是如此。
为区分含义,还有另一列带有整数,该整数指定名称列中内容的类型。
此表的架构如下(简化):
ID int
dtype int
name varchar(50)
因此,示例可能如下所示:
ID dtype name
---------------------------
1 0 Smith
2 0 Trump
3 1 ABC Ltd.
4 1 XYZ Ltd.
我正在尝试使用以下T-SQL代码对此进行标准化:
WITH companies AS
(
SELECT ID, name AS company
FROM nametable WHERE dtype=1
),
people AS
(
SELECT ID, name AS person
FROM nametable WHERE dtype=0
),
SELECT * FROM companies UNION ALL SELECT * FROM people;
我希望得到的是一个带有模式的新表:
ID
dtype
company
person
或者,在表格视图中:
ID dtype person company
------------------------------------------
1 0 Smith
2 0 Trump
3 1 ABC Ltd.
4 1 XYZ Ltd.
相反,该字段现在仅称为person
,而不是name
,但它仍然只是两种信息类型的一个字段。
我知道我可以创建一个新表并将每个部分结果插入其中,但是似乎应该有一个更简单的方法。任何建议表示赞赏。
答案 0 :(得分:2)
您根本不需要使用UNION
。更好的方法是使用一些聚合。
SELECT ID,
MAX(CASE WHEN dtype = 0 THEN [name] END) AS company
MAX(CASE WHEN dtype = 1 THEN [name] END) AS person
FROM nametable
GROUP BY ID;
UNION (ALL)
并不“关心”别名。它将接收到的数据集合并为1。所有数据集必须具有相同的定义,返回的数据集将具有相同的定义。如果数据集的列别名不同,则将使用第一个数据集中提供的别名。 UNION
不会检测到数据集的列名称不同,因此将不同的名称作为不同的列返回;这不是UNION
所做的。
Edit:好吧,这将为OP提供所需的数据,但是,不需要聚合。老实说,我希望ID可以作为共享资源。因为那是通常,这是您唯一拥有此类可怕表格的时间。它不仅使该表更加混乱……
答案 1 :(得分:2)
看来您需要帮助的情况下
select ID, dtype,case when dtype=0 then name end AS company,
case when dtype=1 then name end AS person
FROM nametable
CASE语句遍历条件,并在条件满足时返回一个值,从您的示例输入和输出中清除您要创建类型明智的新列,因此我使用了case语句