oracle 如何使用相同的SQL查询多个日期?

tpxzln5u  于 2023-11-17  发布在  Oracle
关注(0)|答案(3)|浏览(233)

我有以下选择查询

  1. (
  2. SELECT COUNT(*)
  3. FROM TABLE
  4. WHERE birth_date >= TO_DATE(:start_date1, 'YYYY/MM/DD')
  5. AND birth_date <= TO_DATE(:end_date1, 'YYYY/MM/DD')
  6. ) AS count1

字符串
我还需要找到start_date2end_date2的计数,这将导致单独的变量count2
获取count2的最佳方法是什么?
我重写了查询,并将start_date1end_date1替换为start_date2end_date2。有没有其他方法可以不重写查询?

jtoj6r0c

jtoj6r0c1#

如果你想避免重写整个查询,你可以通过使用CTE(公共表表达式)来计算单个查询中两个日期范围的计数来实现这一点。这种方法并没有完全消除重写查询,但封装了共享逻辑。下面是一个使用CTE的示例:

  1. WITH DateRanges AS (
  2. SELECT
  3. (SELECT COUNT(*)
  4. FROM TABLE
  5. WHERE birth_date >= TO_DATE(:start_date1, 'YYYY/MM/DD')
  6. AND birth_date <= TO_DATE(:end_date1, 'YYYY/MM/DD')) AS count1,
  7. (SELECT COUNT(*)
  8. FROM TABLE
  9. WHERE birth_date >= TO_DATE(:start_date2, 'YYYY/MM/DD')
  10. AND birth_date <= TO_DATE(:end_date2, 'YYYY/MM/DD')) AS count2
  11. )
  12. SELECT count1, count2
  13. FROM DateRanges;

字符串
此SQL查询使用一个名为DateRanges的CTE,通过对每个日期范围使用单独的SELECT NULL(*)子查询来计算count1和count2,而无需重复整个查询逻辑。此方法允许您在一次查询执行中计算这两个计数。

展开查看全部
eivnm1vs

eivnm1vs2#

您可以连接一个返回每个日期的子查询,然后使用GROUP BY

  1. SELECT t1.start_date, t1.end_date, COALESCE(COUNT(t2.birth_date), 0) AS count
  2. FROM (
  3. SELECT :start_date1 AS start_date, :end_date1 AS end_date
  4. UNION ALL
  5. SELECT :start_date2 AS start_date, :end_date2 AS end_date
  6. ) t1
  7. LEFT JOIN TABLE t2 ON t2.birth_date BETWEEN t1.start_date AND t1.end_date
  8. GROUP BY t1.start_date, t1.end_date

字符串

lbsnaicq

lbsnaicq3#

您可以使用条件聚合仅查询表一次:

  1. SELECT COUNT(
  2. CASE
  3. WHEN birth_date BETWEEN TO_DATE(:start_date1, 'YYYY/MM/DD')
  4. AND TO_DATE(:end_date1, 'YYYY/MM/DD')
  5. THEN 1
  6. END
  7. ) AS count1,
  8. COUNT(
  9. CASE
  10. WHEN birth_date BETWEEN TO_DATE(:start_date2, 'YYYY/MM/DD')
  11. AND TO_DATE(:end_date2, 'YYYY/MM/DD')
  12. THEN 1
  13. END
  14. ) AS count2
  15. FROM TABLE
  16. WHERE birth_date BETWEEN LEAST(TO_DATE(:start_date1, 'YYYY/MM/DD'), TO_DATE(:start_date2, 'YYYY/MM/DD'))
  17. AND GREATEST(TO_DATE(:end_date1, 'YYYY/MM/DD'), TO_DATE(:end_date2, 'YYYY/MM/DD'))

字符串
如果你想把它作为一个大型查询的一部分,那么CROSS JOIN

  1. SELECT d.*,
  2. c.count1,
  3. c.count2
  4. FROM DUAL d
  5. CROSS JOIN (
  6. SELECT COUNT(
  7. CASE
  8. WHEN birth_date BETWEEN TO_DATE(:start_date1, 'YYYY/MM/DD')
  9. AND TO_DATE(:end_date1, 'YYYY/MM/DD')
  10. THEN 1
  11. END
  12. ) AS count1,
  13. COUNT(
  14. CASE
  15. WHEN birth_date BETWEEN TO_DATE(:start_date2, 'YYYY/MM/DD')
  16. AND TO_DATE(:end_date2, 'YYYY/MM/DD')
  17. THEN 1
  18. END
  19. ) AS count2
  20. FROM TABLE
  21. WHERE birth_date BETWEEN LEAST(TO_DATE(:start_date1, 'YYYY/MM/DD'), TO_DATE(:start_date2, 'YYYY/MM/DD'))
  22. AND GREATEST(TO_DATE(:end_date1, 'YYYY/MM/DD'), TO_DATE(:end_date2, 'YYYY/MM/DD'))
  23. ) c;

展开查看全部

相关问题