mysql中的复杂查询

时间:2010-06-06 18:50:27

标签: sql mysql

我有两张表reportsholidays

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     |            |
   +----------+-----------+---------+------------+

如何修改上述查询以获得所需的输出(针对特定用户(在本例中为gautam))?

修改

我还有一个表dates(date date),其中包含2009-01-012020-12-31之间的所有日期

2 个答案:

答案 0 :(得分: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'

答案 1 :(得分:1)

马克的答案会很有效,但你做的事情很糟糕 - 你正在使用SQL格式化你的信息。这是不好的!您应该仅使用它来检索您的信息,然后使用HTML或您将数据提取到的任何内容对其进行格式化。你的选择应该很简单:

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

如果你需要假期,可另外选一个:

SELECT * from holidays

然后根据需要使用该信息。