SQL-如何仅将一些行值转置为列标题而无数据透视

时间:2018-11-09 20:18:57

标签: sql oracle pivot

我有一个与此类似的表:

stud_ID | first_name | last_name | email | col_num | user_value
1         tom          smith              50         Retail
1         tom          smith              60         Product
2         Sam          wright             50         Retail
2         Sam          wright             60         Sale 

但需要将其转换为:(基本上将'col_num'转换为列标题,并将50更改为函数,将60更改为部门)

 stud_ID | first_name | last_name | email | Function | Department
    1         tom          smith              Retail    Product
    2         Sam          wright             Retail    Sale     

不幸的是,Pivot在我的系统中不起作用,只是想知道是否还有其他方法可以做到这一点?

我到目前为止的代码(很长的列表很抱歉):

SELECT c.person_id_external as stu_id,
  c.lname,
  c.fname,
  c.mi,
  a.cpnt_id,
  a.cpnt_typ_id,
  a.rev_dte,
  a.rev_num,
  cp.cpnt_title AS cpnt_desc,
  a.compl_dte,
  a.CMPL_STAT_ID,
  b.cmpl_stat_desc,
  b.PROVIDE_CRDT,
  b.INITIATE_LEVEL1_SURVEY,
  b.INITIATE_LEVEL3_SURVEY,
  a.SCHD_ID,
  a.TOTAL_HRS,
  a.CREDIT_HRS,
  a.CPE_HRS,
  a.CONTACT_HRS,
  a.TUITION,
  a.INST_NAME,
  --a.COMMENTS,
  a.BASE_STUD_ID,
  a.BASE_CPNT_TYP_ID,
  a.BASE_CPNT_ID,
  a.BASE_REV_DTE,
  a.BASE_CMPL_STAT_ID,
  a.BASE_COMPL_DTE,
  a.ES_USER_NAME,
  a.INTERNAL,
  a.GRADE_OPT,
  a.GRADE,
  a.PMT_ORDER_TICKET_NO,
  a.TICKET_SEQUENCE,
  a.ORDER_ITEM_ID,
  a.ESIG_MESSAGE,
  a.ESIG_MEANING_CODE_ID,
  a.ESIG_MEANING_CODE_DESC,
  a.CPNT_KEY,
  a.CURRENCY_CODE,
  c.EMP_STAT_ID,
  c.EMP_TYP_ID,
  c.JL_ID,
  c.JP_ID,
  c.TARGET_JP_ID,
  c.JOB_TITLE,
  c.DMN_ID,
  c.ORG_ID,
  c.REGION_ID,
  c.CO_ID,
  c.NOTACTIVE,
  c.ADDR,
  c.CITY,
  c.STATE,
  c.POSTAL,
  c.CNTRY,
  c.SUPER,
  c.COACH_STUD_ID,
  c.HIRE_DTE,
  c.TERM_DTE,
  c.EMAIL_ADDR,
  c.RESUME_LOCN,
  c.COMMENTS,
  c.SHIPPING_NAME,
  c.SHIPPING_CONTACT_NAME,
  c.SHIPPING_ADDR,
  c.SHIPPING_ADDR1,
  c.SHIPPING_CITY,
  c.SHIPPING_STATE,
  c.SHIPPING_POSTAL,
  c.SHIPPING_CNTRY,
  c.SHIPPING_PHON_NUM,
  c.SHIPPING_FAX_NUM,
  c.SHIPPING_EMAIL_ADDR,
  c.STUD_PSWD,
  c.PIN,
  c.PIN_DATE,
  c.ENCRYPTED,
  c.HAS_ACCESS,
  c.BILLING_NAME,
  c.BILLING_CONTACT_NAME,
  c.BILLING_ADDR,
  c.BILLING_ADDR1,
  c.BILLING_CITY,
  c.BILLING_STATE,
  c.BILLING_POSTAL,
  c.BILLING_CNTRY,
  c.BILLING_PHON_NUM,
  c.BILLING_FAX_NUM,
  c.BILLING_EMAIL_ADDR,
  c.SELF_REGISTRATION,
  c.SELF_REGISTRATION_DATE,
  c.ACCESS_TO_ORG_FIN_ACT,
  c.NOTIFY_DEV_PLAN_ITEM_ADD,
  c.NOTIFY_DEV_PLAN_ITEM_MOD,
  c.NOTIFY_DEV_PLAN_ITEM_REMOVE,
  c.NOTIFY_WHEN_SUB_ITEM_COMPLETE,
  c.NOTIFY_WHEN_SUB_ITEM_FAILURE,
  c.LOCKED,
  c.PASSWORD_EXP_DATE,
  c.SECURITY_QUESTION,
  c.SECURITY_ANSWER,
  c.ROLE_ID,
  c.IMAGE_ID,
  c.GENDER,
  c.PAST_SERVICE,
  c.LST_UNLOCK_TSTMP,
  c.MANAGE_SUB_SP,
  c.MANAGE_OWN_SP,
  d.col_num,
  d.user_value

FROM pa_cpnt_evthst a,
  pa_cmpl_stat b,
  pa_student c,
  pv_course cp,
  pa_stud_user d
WHERE a.cmpl_stat_id  = b.cmpl_stat_id
AND a.stud_id         = c.stud_id
AND cp.cpnt_typ_id(+) = a.cpnt_typ_id
AND cp.cpnt_id(+)     = a.cpnt_id
AND cp.rev_dte(+)     = a.rev_dte
AND a.CPNT_TYP_ID    != 'SYSTEM_PROGRAM_ENTITY'
AND c.stud_id = d.stud_id
AND d.col_num in ('10','30','50','60')

3 个答案:

答案 0 :(得分:1)

我只会使用条件聚合:

<project-root>/public/images/marker-icon.png

您的代码似乎与示例数据无关。但是我确实注意到您正在使用隐式连接语法。您确实需要学习如何使用正确的,显式的标准 select stud_ID, first_name, last_name, email, max(case when col_num = 50 then user_value end) as function, max(case when col_num = 60 then user_value end) as department from t group by stud_ID, first_name, last_name, email; 语法。

答案 1 :(得分:0)

我假设您有Sql Server 2000或2003。在这种情况下,您需要做的是使用一个光标创建脚本。 该光标将创建具有以下内容的文本: 字符串var =“ CREATE TABLE #Report(Col1 VARCHAR(20),Col2,VARCHAR(20),” + ColumnName

这样,您可以即时创建一个临时表,最后,您需要对“临时表”进行选择以准备好数据透视表。

如果您不熟悉游标,那就没那么容易了。

OR

如果“数据透视”列上的值很少,并且这些值不会增长,您也可以执行以下操作:

Pivot using SQL Server 2000

答案 2 :(得分:0)

我无法理解您的代码,因此我仅假设示例数据中提到的表为stud(因为stud_id)。 所以这就是我认为可以做的枢纽工作。

SELECT  ISNULL(s1.stud_ID, s2.stud_id), 
        ISNULL(s1.first_name, s2.first_name), 
        ISNULL(s1.last_name, s2.last_name), 
        ISNULL(s1.email, s2.email), 
        s1.user_value as [Function], s2.user_value as Department
FROM stud s1 OUTER JOIN stud s2
ON s1.stud_ID = s2.stud_ID -- Assuming stud_ID is primary key, else join on all primary keys
AND s1.col_num = 50 AND s2.col_num = 60

说明:我只是在这里尝试模拟PIVOT的作用。对于所需的每一列,您都在JOIN中创建一个新表,并将其约束为col_num列中的一个值。例如,如果s1中没有50的值,则OUTER JOIN将变为NULL,我们需要从s2中提取记录。

注意:如果需要两个以上的新列,则可以使用COALESCE代替ISNULL