Oracle sql在MONDAY字段中获取有价值的用户如果今天是星期一

时间:2018-05-16 07:19:55

标签: sql oracle

我有一张表,其中包含一周中每一天的字段名称。我正在尝试编写一个SQL查询,该查询将获取当前工作日的星期几字段中没有空值的所有用户。

例如,如果今天是星期一,那么从我的表中获取“星期一”字段的所有用户都不为空。

它将每天运行,因此需要评估每天的哪一天,并获得当天的相应用户。

我发现这段代码片段可以获取星期几,但我不确定如何在另一个select语句中使用:

USER | 123456
SUNDAY | 
MONDAY | 18
TUESDAY | 
WEDNESDAY | 15
THURSDAY | 
FRIDAY | 
SATURDAY | 11   
 ---
USER | 789023
SUNDAY | 18
MONDAY | 
TUESDAY | 3
WEDNESDAY | 15
THURSDAY | 
FRIDAY | 
SATURDAY | 11

任何帮助将不胜感激!

编辑添加样本数据和输出:

  USER | 123456         

所以周一输出将是:

 USER | 789023  

周二输出结果为:

proxy

5 个答案:

答案 0 :(得分:1)

您可以使用TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' )将星期几作为数字(0 =星期一,6 =星期日),这与NLS会话参数无关

使用:

  • TO_CHAR( datavalue, 'D' )会在不同的地区提供一周中不同的第一天;和
  • TO_CHAR( datevalue, 'DAY' )将以不同语言提供不同的值;
  • 但使​​用TRUNC( datevalue, 'IW' )与所有这些问题无关。)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name (
  "USER"    INT,
  SUNDAY    INT,
  MONDAY    INT,
  TUESDAY   INT,
  WEDNESDAY INT,
  THURSDAY  INT,
  FRIDAY    INT,
  SATURDAY  INT
);

INSERT INTO table_name
SELECT 123456, NULL, 18, NULL, 15, NULL, NULL, 11 FROM DUAL UNION ALL
SELECT 789023, 18, NULL, 3, 15, NULL, NULL, 11 FROM DUAL;

查询1

SELECT *
FROM   (
  SELECT "USER",
         CASE TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' )
         WHEN 0 THEN MONDAY
         WHEN 1 THEN TUESDAY
         WHEN 2 THEN WEDNESDAY
         WHEN 3 THEN THURSDAY
         WHEN 4 THEN FRIDAY
         WHEN 5 THEN SATURDAY
         WHEN 6 THEN SUNDAY
         END AS value
  FROM   table_name
)
WHERE  value IS NOT NULL

<强> Results

|   USER | VALUE |
|--------|-------|
| 123456 |    15 |
| 789023 |    15 |

答案 1 :(得分:0)

此查询返回缩写日(周日 - 周六):

select to_char(sysdate,'DY') from dual;

它更容易测试。

您可以编写返回正确列的查询,如下所示:

select case to_char(sysdate,'DY') 
    when 'MON' then monday
    when 'TUE' then tuesday
    when 'WED' then wednesday
    when 'THU' then thursday
    when 'FRI' then friday
    when 'SAT' then saturday
    when 'SUN' then sunday
    else NULL
end 
from yourtable;

答案 2 :(得分:0)

使用Connect By level,您可以获得一周中的相应数字:

select to_char(sysdate+level,'D','NLS_DATE_LANGUAGE=Turkish') "Day No", 
       to_char(sysdate+level,'Day','NLS_DATE_LANGUAGE=Turkish') "Day(Of Week)"
  from dual 
connect by level <= 7 
order by 1;

此外,可能会创建一个视图来使用像表一样的值( NLS_DATE_LANGUAGE参数可能与您的本地设置相关):

create view v_days as
select to_char(sysdate+ level,'D','NLS_DATE_LANGUAGE=Turkish') day_no , 
       to_char(sysdate+ level,'Day','NLS_DATE_LANGUAGE=Turkish') day
  from dual 
connect by level <= 7 
order by 1;

答案 3 :(得分:0)

你可以用这个:

假设您的表格有7列名称sundaymonday,...

SELECT user_column --user_id
FROM table_name
WHERE (
        TO_CHAR(sysdate, 'D') = 1 AND sunday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 2 AND monday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 3 AND tuesday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 4 AND wednesday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 5 AND thursday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 6 AND friday IS NOT NULL
        OR TO_CHAR(sysdate, 'D') = 7 AND saturday IS NOT NULL
    );

答案 4 :(得分:0)

如果您希望坚持使用日期名称而不是计算的偏移量,则可以使用the optional third argument to the to_char() function来避免the session-NLS issues @MTO指出:

to_char(sysdate, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH'

会给你一整天的英文名字。 (请注意,您不能使用它来获取D元素的特定于查询的解释; FM也会删除通常的右边距,以使所有名称的长度相同;不会真的很重要...)

作为CTE中包含数据的演示,列名称更改为有效:

with your_table (user_id, sunday, monday, tuesday, wednesday, thursday, friday, saturday)
as (
            select 123456, null, 18, null, 15, null, null, 11 from dual
  union all select 789023, 18, null, 3, 15, null, null, 11 from dual
)
select user_id
from your_table
where case to_char(sysdate, 'FMDAY', 'NLS_DATE_LANGUAGE=ENGLISH')
    when 'SUNDAY' then sunday
    when 'MONDAY' then monday
    when 'TUESDAY' then tuesday
    when 'WEDNESDAY' then wednesday
    when 'THURSDAY' then thursday
    when 'FRIDAY' then friday
    when 'SATURDAY' then saturday
  end is not null;

   USER_ID
----------
    123456
    789023

今天发现两个用户都是星期三。