これは期待どおりに機能します。
SELECT "Mike" AS FName
これは、「クエリ入力には少なくとも1つのテーブルまたはクエリが含まれている必要があります」というエラーで失敗します。
SELECT "Mike" AS FName
UNION ALL
SELECT "John" AS FName
これはJet/ACEデータベースエンジンの癖/制限ですか、それとも何かが足りませんか?
あなたは何も見落としていませんでした。 Accessのデータベースエンジンは、SELECT
データソースなしで単一行FROM
を許可します。ただし、複数の行をUNION
またはUNION ALL
する場合は、そのデータソースからフィールドを参照していない場合でも、FROM
...を含める必要があります。
1行のテーブルを作成し、チェック制約を追加して、常に1行のみになるようにしました。
Public Sub CreateDualTable()
Dim strSql As String
strSql = "CREATE TABLE Dual (id COUNTER CONSTRAINT pkey PRIMARY KEY);"
Debug.Print strSql
CurrentProject.Connection.Execute strSql
strSql = "INSERT INTO Dual (id) VALUES (1);"
Debug.Print strSql
CurrentProject.Connection.Execute strSql
strSql = "ALTER TABLE Dual" & vbNewLine & _
vbTab & "ADD CONSTRAINT there_can_be_only_one" & vbNewLine & _
vbTab & "CHECK (" & vbNewLine & _
vbTab & vbTab & "(SELECT Count(*) FROM Dual) = 1" & vbNewLine & _
vbTab & vbTab & ");"
Debug.Print strSql
CurrentProject.Connection.Execute strSql
End Sub
そのDual
テーブルは、次のようなクエリに役立ちます。
SELECT "foo" AS my_text
FROM Dual
UNION ALL
SELECT "bar"
FROM Dual;
私が見たもう1つのアプローチは、SELECT
ステートメントをTOP 1
またはWHERE
句とともに使用して、結果セットを1行に制限することです。
チェック制約はJet4で追加され、ADOから実行されたステートメントでのみ使用可能であることに注意してください。 CurrentProject.Connection.Execute strSql
はADOオブジェクトであるため、CurrentProject.Connection
は機能します。DAOで同じステートメントを実行しようとした場合(つまり、CurrentDb.Execute
またはAccessクエリデザイナから) 、DAOはチェック制約を作成できないため、構文エラーが発生します。
一部のシステムテーブルにアクセスできる場合は、次の方法でデュアルテーブルをエミュレートできます。
(SELECT COUNT(*) FROM MSysResources) AS DUAL
残念ながら、私はそのようなシステムテーブルを知りません...
DUAL
やDB2のSYSIBM.DUAL
など、1つのレコードのみが含まれますだからあなたは書くだろう:
SELECT 'Mike' AS FName
FROM (SELECT COUNT(*) FROM MSysResources) AS DUAL
UNION ALL
SELECT 'John' AS FName
FROM (SELECT COUNT(*) FROM MSysResources) AS DUAL
これは、たとえば jOOQ で構文要素として実装されているものです。
データベースへの読み取り専用アクセスを制限している場合(つまり、新しいテーブルを作成したり、システムリソースにアクセスしたりできない場合)、これは機能する可能性があります。
SELECT "Mike" AS FName
FROM (SELECT COUNT(*) FROM anyTable WHERE 1=0) AS dual
anyTableは、最初に見つけたユーザーテーブルです(ユーザーテーブルのない実際のデータベースはほとんど想像できません!)。
WHERE 1 =は、大きなテーブルであっても、0のカウントを高速で返すことになっています(Jetエンジンがそのような些細な状態を認識するのに十分スマートであることを願っています)。
これを行うためのはるかに簡単な方法は次のとおりです。
SELECT 'foo', 'boo', 'hoo' from TableWith1Row
union
SELECT 'foo1', 'boo1', 'hoo1' from TableWith1Row
重要:TableWith1Rowは、文字通り1つのレコードを持つテーブルにすることができます(とにかく無視します)OR任意の数の行を持つテーブルにすることができます(AT = LEAST 1 row)ただし、WHERE句を追加して、1行を確保します。これは少しお粗末ですが、テーブルを追加せずにこれを機能させる簡単な方法です。
テーブル名を入力します(実際にテーブルから列を選択する必要はありません)。
このクエリは、ドロップダウンに必要な3会計年度を示します。会計年度は7月に始まります。
SELECT IIf(Month(Now())>6,Year(Now())-1,Year(Now())-2) AS FY
FROM table
UNION
SELECT IIf(Month(Now())>6,Year(Now()),Year(Now())-1) AS FY
FROM table
UNION
SELECT IIf(Month(Now())>6,Year(Now())+1,Year(Now())) AS FY
FROM table;
トップ1の方法を使用したい場合は、次のようになります。
SELECT first_name AS FName
FROM tblname
UNION ALL
SELECT "Mike" as Fname
FROM (Select Top 1 Count(*) FROM tblsometable);
フィールドのエイリアスは、ユニオンの両側で同じである必要があります。この場合は「FName」です。