【问题标题】:Need help for Cross Tab SQL Query跨表 SQL 查询需要帮助
【发布时间】:2011-09-19 14:12:57
【问题描述】:

这是源示例表:

用户 ID 用户名类型 用户名 1 名字 FN1 1 姓 LN1 2 名字 FN2 2 姓 LN2 3 名字 FN3 3 姓 LN3 4 名字 FN4 4 姓 LN4

我想要一个 SQL 查询来显示我的结果,如下面的给定格式。

用户 ID 名字 姓氏 1 FN1 LN1 2 FN2 液氮 3 FN3 液氮3 4 FN4 液氮

在这方面需要更多帮助...

谢谢, 尤加尔

【问题讨论】:

  • 我个人会重新设计,因为这是一个非常糟糕的设计选择,随着时间的推移会导致一些主要的性能问题。谷歌使用 EAV 表的问题。
  • 您好 HLGEM,我刚刚给出了一个示例,说明我拥有什么样的数据以及我期望从中得到什么结果集。
    请参考实际问题的附图。
    我已经尝试过 Dems 建议的解决方案,但无法解决实际问题。谢谢尤格尔
  • 大家好,mellamokb 建议的解决方案在这里工作...

标签: mysql sql sql-server-2005 sql-server-2008


【解决方案1】:

一种简单的交叉表方法(我个人更喜欢)是使用带有 MAX(CASE WHEN...) 模式的 group by 运算符来控制交叉表字段。这很容易理解 IMO 并且很容易扩展到更多领域。我不确定性能。

select
    UserID,
    max(case when usernametype='First Name' then username end) as FirstName,
    max(case when usernametype='Last Name' then username end) as LastName
from
    MyTable T
group by
    UserID

【讨论】:

  • +1 :对于我要加入的两个字段,作为n 字段的一般解决方案,这正是我要走的路。 (虽然如果有很多属性类型,我会在 WHERE 子句中将它们过滤到我正在使用的那些。)
  • 感谢 mellamokb,终于找到了解决方案...谢谢,Yugal
【解决方案2】:
SELECT
  [fn].UserID,
  [fn].UserName,
  [ln].UserName
FROM
  yourTable AS [fn]
INNER JOIN
  yourTable AS [ln]
    ON [fn].UserID = [ln].UserID
WHERE
      [fn].UserNameType = 'FirstName'
  AND [ln].UserNameType = 'LastName'

【讨论】:

  • 嗨,Dems,您的查询适用于提到的 User 表,但我需要更多关于类似类型表结构的帮助,请查看附件图片。
  • 当我在此处给出的表中应用您的查询时,它会复制结果集。
  • Dems,我在最初提出的问题下方附上了一张实际问题的图片。它与 doctype 和 docname 有关。
  • 我不知道是不是只有我,但我看不到任何图像,也看不到任何图像链接...
【解决方案3】:

你可以使用子查询

SELECT 
    UserID,
    UserName as FirstName,
    (SELECT top 1 UserName 
     FROM myTable 
     WHERE UserID = t.UserID 
     and UserNameType = 'Last Name') as LastName
FROM myTable t
WHERE t.UserNameType = 'First Name'

【讨论】:

  • 两者都可以,只有测试才能揭示哪种情况更适合这种情况
【解决方案4】:

为了避免子查询和可能产生的速度损失,请加入自己的行列。

SELECT DISTINCT
 T1.UserID UserID, 
 T1.UserName FirstName, 
 T2.UserName LastName
FROM 
 Users T1 JOIN Users T2 
  ON T1.UserID = T2.userID
WHERE 
 T1.UserNameType = 'FirstName'
 AND T2.UserNameType = 'LastName'

编辑:现在应该修复了。

【讨论】:

  • 这将为每个 UserID 提供两次,一次将 FirstName 和 LastName 字段放回前面。
【解决方案5】:

假设你有下表

create table #temp1
(
    UserID  int,
    usernametype varchar(10),
    username varchar(10)
)

以下是插入

insert into #temp1(userid, usernametype, username) valueS(1, 'First Name', 'FN1')
insert into #temp1(userid, usernametype, username) valueS(1, 'Last Name', 'LN1')
insert into #temp1(userid, usernametype, username) valueS(2, 'First Name', 'FN2')
insert into #temp1(userid, usernametype, username) valueS(2, 'Last Name', 'LN2')
insert into #temp1(userid, usernametype, username) valueS(3, 'First Name', 'FN3')
insert into #temp1(userid, usernametype, username) valueS(3, 'Last Name', 'LN3')
insert into #temp1(userid, usernametype, username) valueS(4, 'First Name', 'FN4')
insert into #temp1(userid, usernametype, username) valueS(4, 'Last Name', 'LN4')

SQL 查询

SELECT  userid, [First Name], [Last Name]
FROM    
( 
    SELECT userid, usernametype, username FROM #temp1
) 
p 
PIVOT 
( 
    Max(username) FOR usernametype 
    IN ([First Name], [Last Name])
) AS pvt

最终结果集

【讨论】:

  • 你在你的查询窗口中试过这个吗?:) 没有你描述的那么可怕 :)
  • 我认为,它比子查询更好(表现得像每条记录的循环)
  • 请。还要检查查询成本。
  • 表扫描与您的相比减少了 50%。仅供参考,如果缺少非聚集索引。想象一下,如果我实现它会怎样。原因是您的子查询
  • 令我惊讶的是,我忘记了 PIVOT 已经存在了这么久。但现在我记得,我有时不得不避免它是有原因的... 如果旋转字段合法地都包含 NULL 值,那么 PIVOT 会将它们从结果集中删除。真是个 git :( 但这正是这里需要的,所以它得到了我的投票 :)
猜你喜欢
  • 2011-04-03
  • 1970-01-01
  • 2016-07-04
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
相关资源
最近更新 更多