编辑2
我有两张表reports
和holidays
。
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-04 |
| 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-09';
我得到了以下输出
+----------+-----------+---------+------------+
| date | activity | hours | holiday |
+----------+-----------+---------+------------+
|2009-01-04| coding | 1 | |
+----------+-----------+---------+------------+
但我期待这个
+----------+-----------+---------+------------+
| date | activity | hours | holiday |
+----------+-----------+---------+------------+
|2009-01-01| Absent | Absent | |
+----------+-----------+---------+------------+
|2009-01-02| | | Diwali |
+----------+-----------+---------+------------+
|2009-01-03| Absent | Absent | |
+----------+-----------+---------+------------+
|2009-01-04| Coding | 1 | |
+----------+-----------+---------+------------+
|2009-01-05| | | Holi |
+----------+-----------+---------+------------+
|2009-01-06| Absent | Absent | |
+----------+-----------+---------+------------+
|2009-01-07| Absent | Absent | |
+----------+-----------+---------+------------+
|2009-01-08| Absent | Absent | |
+----------+-----------+---------+------------+
|2009-01-09| Absent | Absent | |
+----------+-----------+---------+------------+
如何修改上述查询以获得所需的输出(针对特定用户(在本例中为gautam))?
答案 0 :(得分:1)
更新2:以下是您的新问题的答案。请注意,您错误地使用了CASE语句 - 如果{1}}不为空,则COALESCE(reports.activity, 'Absent')
将返回reports.activity
,如果是'Absent'
,则返回dates
。
首先,您需要一个表CREATE TABLE dates (date date);
,其中包含您要检查的日期,如下所示:
date
----------
2009-01-01
2009-01-02
2009-01-03
2009-01-04
2009-01-05
2009-01-06
2009-01-07
2009-01-08
2009-01-09
2009-01-10
然后立即手动填写:
SELECT dates.date AS date,
CASE WHEN holiday_name IS NULL THEN COALESCE(user_reports.activity, 'Absent')
ELSE '' END AS activity,
CASE WHEN holiday_name IS NULL THEN COALESCE(user_reports.hours, 'Absent')
ELSE '' END AS hours,
COALESCE(holidays.holiday_name, '') AS holiday_name
FROM dates
LEFT OUTER JOIN
(SELECT * FROM reports WHERE reports.username='guatam') AS user_reports
ON dates.date = user_reports.report_date
LEFT OUTER JOIN holidays ON dates.date = holidays.holiday_date
WHERE dates.date>='2009-01-01' and dates.date<='2009-01-09';
这可以在程序上创建,但这完全是另一个主题。
这是查询,使用左外连接和嵌套选择:
date activity hours holiday_name
---------- ---------- ---------- ------------
2009-01-01 Absent Absent
2009-01-02 Diwali
2009-01-03 Absent Absent
2009-01-04 coding 1
2009-01-05 Holi
2009-01-06 Absent Absent
2009-01-07 Absent Absent
2009-01-08 Absent Absent
2009-01-09 Absent Absent
返回:
SELECT * FROM reports WHERE username='guatam'
AND date>='2009-01-01' AND date<='2009-01-9'
但真正的问题是你正在做一些非常糟糕的做法 - 你正在使用SQL格式化你的信息。这很糟糕!您应该只使用它来检索您的信息,然后使用HTML或任何您将数据提取到的格式进行格式化。你的选择应该很简单:
SELECT * from holidays
如果你需要假期,可另外选一个:
{{1}}
然后根据需要使用该信息。
答案 1 :(得分:0)
答案 2 :(得分:0)
这是上面colinmarc答案的延伸,只是为了说明如何避免在假期中“缺席”。否则答案与他的答案大致相同。
SELECT
d.adate AS `date`,
CASE WHEN holiday_name IS NULL THEN coalesce(activity, 'Absent')
ELSE '' END AS activity,
CASE WHEN holiday_name IS NULL THEN coalesce(hours, 'Absent')
ELSE '' END AS activity,
coalesce(holiday_name, '')
FROM (
SELECT holiday_date AS adate FROM holidays
UNION
SELECT report_date AS adate FROM reports
) d
LEFT JOIN reports r ON (d.adate = r.report_date)
LEFT JOIN holidays h ON (d.adate = h.holiday_date)
ORDER BY adate ASC