簡體   English   中英

將多個SELECT查詢合並為一個

[英]Combining multiple SELECT queries in one

正如標題所說,查詢需要組合多個選擇查詢。 問題如下:

顯示員工總數,以及1995,1996,1997,1998中雇用的員工總數。

我的查詢:

select (select count(*) from employees) as "Total",
       (select count(*) from employees where hire_date between 'JAN-1-0095' and 'DEC-1-0095')as "1995",
       (select count(*) from employees where hire_date between 'JAN-1-0096' and 'DEC-1-0096') as "1996",
       (select count(*) from employees where hire_date between 'JAN-1-0097' and 'DEC-1-0097') as "1997",
       (select count(*) from employees where hire_date between 'JAN-1-0098' and 'DEC-1-0098') as "1998" 
from employees

但問題是,不是僅返回單個記錄,而是對表中的所有記錄執行此查詢,從而產生以下輸出:

在此輸入圖像描述

您可以使用條件計數:

select count(*) as total_count, 
       count(case when extract(year from hire_date) = 1995 then 1 end) as "1995",
       count(case when extract(year from hire_date) = 1996 then 1 end) as "1996",
       count(case when extract(year from hire_date) = 1997 then 1 end) as "1997",
       count(case when extract(year from hire_date) = 1998 then 1 end) as "1997",
from employees;

這利用了聚合函數忽略NULL值這一事實,因此count()只計算case表達式返回非null值的那些行。


您的查詢為employees表中的每一行返回一行,因為您不應用任何分組。 每個select都是一個標量子選擇,它為employees表中的每一行執行。

如果你用from dual替換from employees的最終結果from employees可以讓它只返回一行 - 但你仍然會計算每個子選擇中的所有行。


您還應該像您一樣避免隱式數據類型轉換。 'JAN-1-0095'是一個字符串,將根據您的NLS設置隱式轉換為date 如果從我的計算機執行,您的查詢將無法運行(因為NLS設置不同)。

當你正在尋找一整年時,只需比較年份就可以更短,更容易理解(至少在我看來)。

另一個選擇是使用正確的日期文字,例如where hire_date between DATE '1995-01-01' and DATE '1995-12-31' where hire_date between to_date('1995-01-01', 'yyyy-mm-dd') and to_date('1995-12-31', 'yyyy-mm-dd')或使用Oracle的to_date()函數更冗長: where hire_date between to_date('1995-01-01', 'yyyy-mm-dd') and to_date('1995-12-31', 'yyyy-mm-dd')

假設這些年份確實是您想要的,那么您的查詢的問題在於您是從employees進行選擇,因此您可以為每個employees選擇一行。 你可以使用:

select (select count(*) from employees) as "Total",
       (select count(*) from employees where hire_date between 'JAN-1-0095' and 'DEC-1-0095')as "1995",
       (select count(*) from employees where hire_date between 'JAN-1-0096' and 'DEC-1-0096') as "1996",
       (select count(*) from employees where hire_date between 'JAN-1-0097' and 'DEC-1-0097') as "1997",
       (select count(*) from employees where hire_date between 'JAN-1-0098' and 'DEC-1-0098') as "1998" 
from dual;

我會使用date '1998-01-01'作為日期常量。

但是,我更喜歡@ a_horse_with_no_name的解決方案。

你應該避免使用很多子查詢。 你應該試試這個:


SQL Server:

SELECT count(*) as Total, hire_date 
FROM employees
WHERE year(hire_date) IN ('1995','1996','1997','1998') 
GROUP BY hire_date WITH CUBE

在ORACLE中

SELECT count(*) as Total, hire_date 
FROM employees
WHERE extract(year from hire_date) IN ('1995','1996','1997','1998') 
GROUP BY CUBE (hire_date)

除了GROUP BY生成的小計之外,CUBE擴展還將為每個hire_date生成小計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM