2010-06-06 246 views
2

我有兩個表reportsholidaysmysql中的複雜查詢

reports(username varchar(30),activity varchar(30),hours int(3),report_date date)

holidays(holiday_name varchar(30), holiday_date date)

select * from reports

+----------+-----------+---------+------------+ 
| username | activity | hours | date  | 
+----------+-----------+---------+------------+ 
| prasoon | testing | 3 | 2009-01-01 | 
| prasoon | coding | 4 | 2009-01-03 | 
| gautam | coding | 1 | 2009-01-05 | 
| prasoon | coding | 4 | 2009-01-06 | 
| prasoon | coding | 4 | 2009-01-10 | 
| gautam | coding | 4 | 2009-01-10 | 
+----------+-----------+---------+------------+ 

select * from holidays

+--------------+---------------+ 
| holiday_name | holiday_date | 
+--------------+---------------+ 
| Diwali  | 2009-01-02 | 
| Holi   | 2009-01-05 | 
+--------------+---------------+ 

當我用下面的查詢

SELECT dates.date AS date, 
    CASE 
    WHEN holiday_name IS NULL THEN COALESCE(reports.activity, 'Absent') 
    WHEN holiday_name IS NOT NULL and reports.activity IS NOT NULL THEN reports.activity 
    ELSE '' 
    END 
    AS activity, 
    CASE WHEN holiday_name IS NULL THEN COALESCE(reports.hours, 'Absent') 
    WHEN holiday_name IS NOT NULL and reports.hours IS NOT NULL THEN reports.hours 
    ELSE '' 
    END 
    AS hours, 
    CASE 
    WHEN holiday_name IS NULL THEN COALESCE(holidays.holiday_name, '') 
    ELSE holidays.holiday_name 
    END 
    AS holiday_name 
    FROM dates 
    LEFT OUTER JOIN reports ON dates.date = reports.date 
    LEFT OUTER JOIN holidays ON dates.date = holidays.holiday_date 
    where reports.username='gautam' and dates.date>='2009-01-01' and dates.date<='2009-01-10'; 

我得到了以下輸出

+----------+-----------+---------+------------+ 
    | date | activity | hours | holiday | 
    +----------+-----------+---------+------------+ 
    |2009-01-05| coding | 1 | Holi  | 
    +----------+-----------+---------+------------+ 
    |2009-01-10| coding | 4 |   | 
    +----------+-----------+---------+------------+ 

,但我預計今年

+----------+-----------+---------+------------+ 
    | date | activity | hours | holiday | 
    +----------+-----------+---------+------------+ 
    |2009-01-01| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-02|   |   | Diwali  | 
    +----------+-----------+---------+------------+ 
    |2009-01-03| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-04| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-05| Coding | 1  | Holi  | 
    +----------+-----------+---------+------------+ 
    |2009-01-06| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-07| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-08| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-09| Absent | Absent |   | 
    +----------+-----------+---------+------------+ 
    |2009-01-10| Coding | 4  |   | 
    +----------+-----------+---------+------------+ 

如何修改上面的查詢以獲得所需的輸出(用於特定用戶(高塔姆在這種情況下))?

編輯

我也有一個表dates(date date)包含所有2009-01-01之間的日期2020-12-31

+1

你也有第三個表'日期'。現在我可以猜測這個表的表格結構和內容,但爲了完整性,您可能應該將其添加到問題中。 – 2010-06-06 18:53:33

+0

@mark:謝謝.....編輯:) – Satish 2010-06-06 18:57:02

回答

2

移動JOIN子句中的WHERE子句。我唯一改變的是最後幾行:

FROM dates 
LEFT JOIN reports ON dates.date = reports.date 
AND reports.username='gautam' 
LEFT JOIN holidays ON dates.date = holidays.holiday_date 
AND dates.date >= '2009-01-01' 
AND dates.date <= '2009-01-10' 

你同意這個答案的上方,但進一步的測試表明,雖然它爲你的作品,它沒有爲我工作。下面是一些對我的作品:

FROM dates 
LEFT JOIN reports ON dates.date = reports.date 
AND reports.username='gautam' 
LEFT JOIN holidays ON dates.date = holidays.holiday_date 
WHERE dates.date >= '2009-01-01' 
AND dates.date <= '2009-01-10' 
+0

感謝您的回覆。 – Satish 2010-06-06 19:25:18

+0

@Satish:儘管你已經接受了我的回答,但我認爲我原來的回答並不完全符合你的要求,所以我通過更正來更新它。如果您認爲更新是錯誤的,我可以回滾到您接受的答案。 – 2010-06-06 19:29:20

+0

@Mark Byers:回滾你的答案其實我錯誤地採取了日期的範圍,所以我得到了荒謬的結果,但你以前的答案已經奏效。 – Satish 2010-06-06 19:46:02

1

馬克的回答會是不錯的,但你正在做的東西的做法很可憐 - 你使用SQL格式化您的信息。這不好!您應該只使用它來檢索您的信息,然後使用HTML格式或任何將數據拉入的格式。你的選擇應該是一個簡單:

SELECT * FROM reports WHERE username='guatam' 
AND date>='2009-01-01' AND date<='2009-01-9' 

和一個單獨的一個假期,如果你需要它:

SELECT * from holidays 

然後利用這些信息,因爲你需要。

+0

我不同意 - 當結果集變大時,SQL將比應用程序代碼更好地擴展。其次,問題是關於返回正確的結果,而不是格式。 – 2010-06-06 20:37:55

+0

問題中的大部分查詢都是格式化的 - 使用COALESCE來返回空白空間而不是NULL,並且有一個單獨的日期表,以便每個日期都有一行。即使它的規模更好,只需提取信息就可以改變前端顯示信息的方式,而不會影響查詢。這就是爲什麼它被認爲是不好的做法。 – colinmarc 2010-06-06 20:47:07