2017-01-07 12 views
0

私は、医師と過去の予定を含む予定データベースを持っています。 ユーザが医師への予約を予定したいとき、彼は居住地を選んだ後、その居住地に従って医師を表示する。異なるテーブルからの2つのSQLクエリを結合する

医師は過去の任命の順番で表示されます。つまり、私が過去に2人の心臓病専門医を訪問した場合、最後に私が予約したものが最初に表示されます、彼の後に他の人、そして彼らの後に他のすべての心臓学者と私は決して予定を持っていませんでした。

私は、心臓病専門医と私の過去の予定を探し、日付順に降順に並べ替えてから、すべての医師に行き、リストの一番下に他のものを追加する必要があります。

私はこのクエリをしようとしている:

(
select distinct pastappointments.doctorID from pastappointments where 
    pastappointments.insuredID = 1 and pastappointments.residency='cardio' 
order by pastappointments.appTime desc 
) 
union (
select employees.employeeID from employees where 
employees.Residency='cardio' and employees.employeeID not in (
select distinct pastappointments.doctorID from pastappointments where 
pastappointments.insuredID = 1 and pastappointments.residency='cardio' 
)) 

括弧たら、括弧なしで私は正しい順序を取得しています、労働組合のコマンド上記の最初のクエリを実行しているときに私がいる問題は、主ですクエリの結果が間違ったものに変わります。

私はMySQLを使用しています。

これは、2つのクエリではなく1つのクエリを使用して行いたいですが、必要な降順を失うことなく、そうする方法が見つからないようです。

答えて

2

特定の順序で結果を表示する場合は、最も外側のクエリにorder byを指定する必要があります。

MySQLでは、の後にunionの後になります。あなたが明示的に重複を除去するオーバーヘッドが発生する場合を除き、私も強く、union all代わりのunionをお勧めします。

(select pa.doctorID, max(pa.appTime) as last_apptime 
from pastappointments pa 
where pa.insuredID = 1 and pa.residency = 'cardio' 
group by pa.doctorID 
) union all 
(select e.employeeID, NULL as last_apptime 
from employees e 
where e.Residency = 'cardio' and 
     e.employeeID not in (select pa.doctorID 
          from pastappointments pa 
          where pa.insuredID = 1 and  
            pa.residency = 'cardio' 
          ) 
) 
order by (last_apptime is not null) desc, last_apptime desc; 

これには2つの列を返します。私も最初のクエリでgroup byの使用を注意してください

select t.doctorID 
from (<above query without orderby) t 
order by (last_apptime is not null) desc, last_apptime desc; 

:あなたが1列にしたい場合は、単にサブクエリを使用します。これは、正しい最終予約時間を得るために必要です。

そして、私はすべての医師が従業員であると仮定した場合、これは簡略化され多くのことができます。

select e.employeeID 
from employees e left join 
     (select pa.doctorID, max(apptime) as last_apptime 
     from pastappointments pa 
     where pa.insuredID = 1 and pa.residency = 'cardio' 
     group by pa.doctorId 
    ) pa 
     on e.EmployeeId = pa.DoctorId 
where e.Residency = 'cardio' -- or pa.doctorId is not null 
order by (last_apptime is not null) desc, last_apptime; 

これもe.Residencypa.residencyと同じであることを前提としています。そうでない場合は、orの条件が必要です。

これはクエリを書くためのより合理的な方法です(すべての医師が従業員であると仮定します)。

+0

こんにちは、ありがとうございました! あなたの最初の提案はうまくいきましたが、単純な提案を使用しようとしたときに予期せぬ「どこで」通知されました。 もう一つの小さな質問がありますが、メインの質問を使用しているのですか?DBから返されるのは医師のID番号です。 –

+0

LEFT JOIN( 'pa.doctorID = e.employeeID')のON句がありません。 –

+0

@PaulSpiegel。 。 。ありがとうございました。 –

0

外部クエリで両方のクエリを囲み、でを適用する必要があります。

0

LEFT JOINを使用して、欠落している予定時間を最後に注文する値に置き換えることができます。

select employees.employeeID 
from employees 
left join pastappointments 
    on pastappointments.insuredID = 1 
    and pastappointments.residency='cardio' 
    and pastappointments.doctorID = employees.employeeID 
group by employees.employeeID 
where employees.Residency='cardio' 
order by coalesce(max(pastappointments.appTime), cast(0 as datetime)) desc 
関連する問題