简体   繁体   English

SQL,在查询期间根据数据条件创建新列

[英]SQL, during query create new column based on data conditions

I've managed to cobble together a SQL query that works, using a combination of unions and joins of tables that gives me the interim results I need.我已经设法拼凑出一个有效的 SQL 查询,使用联合和表连接的组合,为我提供了我需要的临时结果。

SELECT  n.study_id AS StudyId,
        n.practice_id AS PracticeId,
    n.FluVaxCode,
    n.Date,
    date(p.BaseStart / 1000, 'unixepoch') AS BaseStart, 
    date(p.BaseEnd / 1000, 'unixepoch') AS BaseEnd,
    date(p.OutcomeStart / 1000, 'unixepoch') AS OutcomeStart, 
    date(p.OutcomeEnd / 1000, 'unixepoch') AS OutcomeEnd,
    CASE WHEN Date BETWEEN BaseStart AND BaseEnd THEN 'Y' ELSE 'N' END AS BaseVax,
    CASE WHEN Date BETWEEN OutcomeStart AND OutcomeEnd THEN 'Y' ELSE 'N' END AS OutcomeVax
FROM toypractice p INNER JOIN
     (SELECT  t.study_id, t.practice_id,
     date(t.event_date / 1000, 'unixepoch') AS Date, 
     t.code_id AS FluVaxCode
     FROM toytherapy t
     WHERE t.code_id IN ('dher.', 'a6b1.', 'bk31.')
     UNION 
     SELECT  c.study_id, c.practice_id, 
     DATE(c.event_date / 1000, 'unixepoch') AS Date, 
     c.code_id AS FluVaxCode
     FROM toyclinical c
     WHERE c.code_id IN ('1383.', '229..', 'X77RW')
     ORDER BY FluVaxCode DESC
     ) n 
     ON p.practice_id = n.practice_id;

I end up with multiple columns including three as:我最终得到多个列,包括三个:

Date, BaseStart, BaseEnd

all of which are in YYYY-MM-DD format (I think).所有这些都是 YYYY-MM-DD 格式(我认为)。 Is there a way, during the query I can tack some code on the end of the query such that it will create a new column in the outputs, such that if Date falls between BaseStart and BaseEnd, the value in the new column will be 'Y', otherwise value in new column will be 'N'?有没有办法,在查询期间,我可以在查询结束时添加一些代码,以便它将在输出中创建一个新列,这样如果 Date 介于 BaseStart 和 BaseEnd 之间,则新列中的值将是' Y',否则新列中的值将是'N'? In this case I'm using sqlite to develop/test but it will eventually have to work in mssqlserver 2019. Thx.在这种情况下,我使用 sqlite 进行开发/测试,但它最终必须在 mssqlserver 2019 中工作。谢谢。 J Ĵ

Try adding the following to your current select list:尝试将以下内容添加到您当前的 select 列表中:

    , CASE WHEN n.Date BETWEEN date(p.BaseStart / 1000, 'unixepoch') AND date(p.BaseEnd / 1000, 'unixepoch') THEN 'a' ELSE 'b' END AS is_between

This can be done in different ways.这可以通过不同的方式来完成。 But the above should work.但上述应该工作。

The fiddle 小提琴

Something like this:像这样的东西:

Specific test case for sqlite, as a starting point. sqlite的具体测试用例,作为起点。

  • cte - provides a couple of rows representing your current query result cte - 提供几行代表您当前的查询结果
  • cte2 - shows how we can convert the date (conv_date) to be compatible with the Base values cte2 - 显示我们如何将日期 (conv_date) 转换为与基本值兼容
  • Final query expression - shows how to use the derived conv_date from cte2 to calculate BETWEEN properly.最终查询表达式 - 显示如何使用从 cte2 派生的 conv_date 正确计算 BETWEEN。

Notice, I left the attempt to use date directly, which produces the wrong is_between result.请注意,我尝试直接使用日期,这会产生错误的is_between结果。 is_between2 shows the correct result. is_between2显示正确的结果。

WITH cte (date, BaseStart, BaseEnd) AS (
         SELECT 1467241200000, '2016-06-20', '2016-06-30' UNION
         SELECT 1467241200000, '2017-06-20', '2017-06-30'
     )
SELECT date(date / 1000, 'unixepoch'), BaseStart, BaseEnd
     , CASE WHEN Date BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between
     , CASE WHEN date(date / 1000, 'unixepoch') BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between2
  FROM cte
;

and also:

WITH cte (date, BaseStart, BaseEnd) AS (
         SELECT 1467241200000, '2016-06-20', '2016-06-30' UNION
         SELECT 1467241200000, '2017-06-20', '2017-06-30'
     )
   , cte2 AS (
         SELECT *
              , date(date / 1000, 'unixepoch') AS conv_date
           FROM cte
     )
SELECT date(date / 1000, 'unixepoch'), BaseStart, BaseEnd
     , CASE WHEN Date      BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between
     , CASE WHEN conv_date BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between2
  FROM cte2
;

Result:结果:

date(date / 1000, 'unixepoch')日期(日期/1000,'unixepoch') BaseStart基础开始 BaseEnd基端 is_between在。。。之间 is_between2 is_between2
2016-06-29 2016-06-29 2016-06-20 2016-06-20 2016-06-30 2016-06-30 b b a一个
2016-06-29 2016-06-29 2017-06-20 2017-06-20 2017-06-30 2017-06-30 b b b b

General answer:一般回答:

SELECT Date, BaseStart, BaseEnd
     , CASE WHEN Date BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between
  FROM ( your SQL ) AS derived_table
;

or

WITH cte AS (
       your sql
     )
SELECT Date, BaseStart, BaseEnd
     , CASE WHEN Date BETWEEN BaseStart AND BaseEnd THEN 'a' ELSE 'b' END AS is_between
  FROM cte
;

You may need to add quoting if you chose identifiers which conflict with reserved or keywords in the SQL language supported by your database.如果您选择的标识符与数据库支持的 SQL 语言中的保留或关键字冲突,则可能需要添加引号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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