将数据从一行获取到多行时,替代UNION操作?

时间:2011-11-17 15:06:14

标签: sql union

我试图将表中一行的数据转换为临时表中的三行,因此我可以根据不同的值更新数据,我想知道是否有比使用UNION更好的方法操作

这是基本的UNION语法,它将数据从一行获取到我想要的三行:

    (SELECT 
    0 as lead_id,
    'RV' as lead_type,
    '' as lead_serial,
    rv_amplitude as amplitude,
    rv_pulse_width as pulse_width,
    rv_sensitivity as sensitivity
    FROM program_parameters WHERE event_id = 33636)
    UNION
    (SELECT
    0 as lead_id,
    'LV' as lead_type,
    '' as lead_serial,
    final_amplitude as amplitude,
    final_pulse_width as pulse_width.
    final_sensitivity as sensitivity
    FROM program_parameters WHERE event_id = 33636)
    UNION
    (SELECT
    0 as lead_id,
    'ATRIAL' as lead_type,
    atrial_amplitude as amplitude,
    atrial_pulse_width as pulse_width,
    atrial_sensitivity as sensitivity
    FROM program_parameters WHERE event_id = 33636)

这样我的最终数据就是一个带有列的三行表。

获取此数据的唯一键值是event_id,表中每个event_id只有一行。

有没有更好的方法将这些数据分成UNION操作以外的其他行?

5 个答案:

答案 0 :(得分:3)

UNION是正确的解决方案。

当您希望将单独的结果集作为一个集合时,需要使用此功能。

答案 1 :(得分:1)

最佳解决方案似乎是Union,但是,您可以尝试使用表变量和交叉连接

DECLARE @t TABLE (lead_type VARCHAR(10))
INSERT INTO @t VALUES ('LV')
INSERT INTO @t VALUES ('RV')
INSERT INTO @t VALUES ('ATRIAL')

SELECT 0 as lead_id,
t.lead_type as lead_type,
'' as lead_serial,
CASE t.lead_type 
  WHEN 'LV' THEN rv_amplitude 
  WHEN 'RV' THEN final_amplitude 
  WHEN 'ATRIAL' THEN atrial_amplitude
END as amplitude,
CASE t.lead_type 
  WHEN 'LV' THEN rv_pulse_width
  WHEN 'RV' THEN final_pulse_width
  WHEN 'ATRIAL' THEN atrial_pulse_width
END as pulse_width,
CASE t.lead_type 
  WHEN 'LV' THEN rv_sensitivity
  WHEN 'RV' THEN final_sensitivity
  WHEN 'ATRIAL' THEN atrial_sensitivity
END as sensitivity
FROM program_parameters
CROSS JOIN @t t
WHERE event_id = 33636

答案 2 :(得分:1)

可能略有改善:

 SELECT 0 as lead_id,
        lead_type,
        '' as lead_serial,
        case lead_type
            when 'RV' then rv_amplitude
            when 'LV' then final_amplitude
            when 'ATRIAL' then atrial_amplitude
        end as amplitude,
        case lead_type
            when 'RV' then rv_pulse_width
            when 'LV' then final_pulse_width
            when 'ATRIAL' then atrial_pulse_width
        end as pulse_width,
        case lead_type
            when 'RV' then rv_sensitivity
            when 'LV' then final_sensitivity
            when 'ATRIAL' then atrial_sensitivity
        end as sensitivity
 FROM (SELECT 'RV' as lead_type union SELECT 'LV' UNION SELECT 'ATRIAL') dummy
 CROSS JOIN program_parameters 
 WHERE event_id = 33636

(非常类似于Jhonny的,但使用内联视图而不是临时表。)

答案 3 :(得分:0)

假设您的意思是传统意义上的临时表... UNION操作涉及解决重复行。在表表达式中使用文字意味着它没有重复的行,因此您可以使用三个单独的INSERT语句。

...但是,你可能指的是派生表,CTE等。

答案 4 :(得分:0)

我最后稍微更改了这个,然后加入第二个表来获取序列号和其他值,之后将lead_area(我的原始问题的lead_type成为lead_area,由于另一列名为lead_type)列添加到第二个表

创建程序usp_IcdLeadProgramming(     @encounterID INT,     @patientID INT ) 如     BEGIN

-- Create temp table for final results.
CREATE TABLE #tmp(
    lead_area VARCHAR(10),  
    amplitude FLOAT, 
    pulse_width FLOAT, 
    sensitivity FLOAT)

-- Get the values out of the program_parameters table record
INSERT INTO #tmp
SELECT 
        'RV' as lead_area, 
        rv_amplitude as amplitude, 
        rv_pulse_width as pulse_width, 
        rv_sensitivity as sensitivity 
FROM    program_parameters 
WHERE   event_id = @encounterID 
UNION
SELECT 
        'LV' as lead_area, 
        final_amplitude as amplitude,
        final_pulse_width as pulse_width,
        final_sensitivity as sensitivity
FROM    program_parameters 
WHERE   event_id = @encounterID
UNION
SELECT 
        'ATRIAL' as lead_area, 
        atrial_amplitude as amplitude,
        atrial_pulse_width as pulse_width,
        atrial_sensitivity as sensitivity
FROM    program_parameters 
WHERE   event_id = @encounterID


-- Get the current leads and join to the values.
SELECT 
        l.lead_id,
        l.lead_type,
        l.lead_serial, 
        l.lead_system, 
        l.lead_location,
        ll.lead_area,
        t.amplitude,
        t.pulse_width,
        t.sensitivity
FROM    
        leads l
INNER JOIN 
        lead_location_type ll
ON      l.lead_location = ll.lead_location_code
INNER JOIN #tmp t
ON      ll.lead_area = t.lead_area
WHERE   l.patient_id = @patientID 
AND     lead_removal_date IS NULL 
AND     ll.lead_area IS NOT NULL 

DROP TABLE #tmp

END