简体   繁体   中英

SQL Server Join Table Statement

Can I join the following 3 statement to display sick_total_day , other_total_day , other_total_day in one row (same where clause) ?

SELECT staff_key, 
       sum(days_applied) as sick_total_day 

from Tleave_sick_leave 

where staff_key = 131 
and from_date>='2011/4/1 00:00:00' 
and to_date<='2011/4/30 00:00:00';


SELECT staff_key, 
       sum(days_applied) as other_total_day 
from Tleave_other_leave 
where staff_key = 131 
and from_date>='2011/4/1 00:00:00' 
and to_date<='2011/4/30 00:00:00';


SELECT staff_key, 
       sum(days_applied) as other_total_day 

from Tleave_vleave 
where staff_key = 131 
and from_date>='2011/4/1 00:00:00' 
and to_date<='2011/4/30 00:00:00';

This would take care of the repeating where clause but comes with a performance penalty.

A better solution might be what EMP suggests. Normalize your tables to remove duplicate data.

SELECT  staff_key
        , SUM(CASE WHEN type = 'Sick' THEN days_applied ELSE 0 END) as sick_total_day       
        , SUM(CASE WHEN type = 'Othert' THEN days_applied ELSE 0 END) as othert_total_day       
        , SUM(CASE WHEN type = 'Otherv' THEN days_applied ELSE 0 END) as otherv_total_day       
FROM    (
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    , [Type] = 'Sick'
            FROM    Tleave_sick_leave
            UNION ALL
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    , 'Othert'
            FROM    Tleave_other_leave
            UNION ALL
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    , 'Otherv'
            FROM    Tleave_vleave
        )
WHERE   staff_key = 131 
        AND from_date>='2011/4/1 00:00:00' 
        AND to_date<='2011/4/30 00:00:00';
GROUP BY
        staff_key

You probably could do it in one statement, but you would still need 3 separate WHERE clauses, because the from_date and to_date columns in each table are completely separate, despite having the same name.

It sounds like you've found an issue in your table design. You have 3 tables with very similar information. If you can combine them into one table then you can probably get away with one query, too.

You can UNION your three tables together to make one set of data. Then you can use PIVOT to transpose the SUM into columns.

This should work. Although I have not tested it with any data.

SELECT
    [Tleave_sick_leave],
    [Tleave_other_leave],
    [Tleave_vleave]
FROM
(
    SELECT
        'Tleave_sick_leave' [Table],
        [staff_key],
        [days_applied],
        [from_date],
        [to_date]
    FROM
        [Tleave_sick_leave]
    UNION ALL
    SELECT
        'Tleave_other_leave' [Table],
        [staff_key],
        [days_applied],
        [from_date],
        [to_date]
    FROM
        [Tleave_other_leave]
    UNION ALL
    SELECT
        'Tleave_vleave' [Table],
        [staff_key],
        [days_applied],
        [from_date],
        [to_date]
    FROM
        [Tleave_vleave]
) [PivotData]
PIVOT
(
    SUM([days_applied])
FOR
    [Table]
IN
    (
        [Tleave_sick_leave],
        [Tleave_other_leave],
        [Tleave_vleave]
    )
) [Data]
WHERE
    [staff_key] = 131
AND
    [from_date] >= '2011/4/1 00:00:00' 
AND
    [to_date] <= '2011/4/30 00:00:00'

NOTE: This is a SQL Server 2005 up approach. If you have 2000 or lower then you will need to go with Lieven's answer which effectively does the same thing.

Little bit amendment for the code provided by Lieven, it works now...

SELECT  a.staff_key
        , SUM(CASE WHEN a.type = 'Sick' THEN 
                        a.days_applied ELSE 0 END) as sick_total_day       
        , SUM(CASE WHEN a.type = 'Othert' THEN
                        a.days_applied ELSE 0 END) as othert_total_day       
        , SUM(CASE WHEN a.type = 'Otherv' THEN 
                        a.days_applied ELSE 0 END) as otherv_total_day       
FROM    
(
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    , type = 'Sick'
            FROM    Tleave_sick_leave
            UNION ALL
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    ,type = 'Othert'
            FROM    Tleave_other_leave
            UNION ALL
            SELECT  staff_key
                    , days_applied
                    , from_date
                    , to_date
                    ,type = 'Otherv'
            FROM    Tleave_vleave
) a
WHERE staff_key = '131' AND 
      from_date>='2011/4/1 00:00:00' AND 
      to_date<='2011/4/30 00:00:00'
GROUP BY staff_key

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM