SQLで問題が発生しています。基本的に、従業員に尋ねられたすべての質問の合計を含む結果セットを取得しようとしています(会社ごとにグループ化されています)。また、手動で追加された項目である「onetime_items」を別のテーブル。
私は現在このSQLステートメントを持っています(私はMySQLを使用しています):
SELECT
CONCAT_WS(
', ', count(DISTINCT CONCAT(emailaddress, '_', e.id)),
(
SELECT GROUP_CONCAT(items SEPARATOR '; ') as OneTimeItems
FROM (
SELECT CONCAT_WS(
': ', oi.item_name, SUM(oi.item_amount)
) items
FROM onetime_item oi
WHERE oi.company_id = e.company_id
AND oi.date BETWEEN '2015-12-01'
AND LAST_DAY('2015-12-01')
GROUP BY oi.item_name
) resulta
)
) as AllItems,
e.id,
LEFT(e.firstname, 1) as voorletter,
e.lastname
FROM question q
LEFT JOIN employee e ON q.employee_id = e.id
WHERE 1=1
AND YEAR(created_at) = '2015'
AND MONTH(created_at) = '12'
GROUP BY e.company_id
今、私は次のエラーを受け取ります:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.company_id' in where clause
使用される日付はダミーの日付であり、下部のwhere句の1 = 1は、ユーザー入力値に基づいてwhereステートメントを生成しているためです。
すべての列はテーブルemployeeに存在し、左の結合は機能します(列参照を使用する代わりに手動でIDを入力してみましたが、機能しました。正しい結果が返されました)
また、申し訳ありませんが、テーブルスキーマやDB構造に関連するものをオンラインで投稿することはできません。
E.company_idへの参照が失敗する理由について何か考えはありますか?
編集:これは私が必要とする結果セットです:
5, Het is je verjaardag: 1; Skivakantie: 1; Telefonische leadvergoeding: 8
構成は次のとおりです。5 =残りを取得するためにリードカンマで区切ります。リードは、質問テーブルの一意の組み合わせであり、残りの結果はonetime_itemsから作成されます。
EDIT 2:SQLフィドルでエラーが発生し続けるので、作成した小さなデータを含む小さな作成したDBを投稿します: http://Pastebin.com/cCveVtGr
問題の原因は コメントの@Phil によって特定されました:
おそらくネストが深すぎるためです
ネストが2層あり、テーブルe
の参照はMySQLでこれらの2層を「見る」ことができません。
通常、相関インラインサブクエリは派生テーブルに変換してから、LEFT
をFROM
句で他のテーブルに結合できますが、それらは非相関に変換する必要があります(MySQLでは。他のDBMSでは、 LATERAL
結合または同様の_OUTER APPLY
_を使用します。
ジョブを完了するための最初の書き換え:
_SELECT
CONCAT_WS(
', ', count(DISTINCT CONCAT(q.emailaddress, '_', e.id)),
dv.OneTimeItems
) as AllItems,
e.id,
LEFT(e.firstname, 1) as voorletter,
e.lastname
FROM question q
LEFT JOIN employee e ON q.employee_id = e.id
LEFT JOIN
(
SELECT company_id,
GROUP_CONCAT(items SEPARATOR '; ') AS OneTimeItems
FROM (
SELECT oi.company_id,
CONCAT_WS(
': ', oi.item_name, SUM(oi.item_amount)
) items
FROM onetime_item oi
WHERE oi.date BETWEEN '2015-12-01'
AND LAST_DAY('2015-12-01')
GROUP BY oi.company_id, oi.item_name
) resulta
GROUP BY company_id
) AS dv
ON dv.company_id = e.company_id
WHERE 1=1
AND YEAR(q.created_at) = '2015'
AND MONTH(q.created_at) = '12'
GROUP BY e.company_id ;
_
SQLfiddleでテストします。
問題のコメントとは無関係:
GROUP BY e.company_id
_がありますが、select
リストにはe.id, LEFT(e.firstname, 1), e.lastname
があります。これらはすべて、各会社の(多かれ少なかれランダムな)従業員からの任意の結果をもたらします-または非常にまれなケースでさえ、2人または3人の異なる従業員からの任意の結果をもたらします! MySQLは(5.7より前では)このようなグループの不適切な使用を許可し、誤った結果を引き起こす可能性がありました。これは5.7で修正されており、デフォルト設定ではこのクエリが拒否されます。状態:
_YEAR(created_at) = '2015' AND MONTH(created_at) = '12'
_
インデックスを使用できません。列がBETWEEN
タイプの包括的および排他的範囲条件である場合、DATE
のいずれかで書き換えることをお勧めします。これは、任意の日時タイプ(DATE
、DATETIME
、TIMESTAMP
)任意の精度:
_-- use only when the type is DATE only
date BETWEEN '2015-12-01' AND LAST_DAY('2015-12-01')
_
または:
_-- use when the type is DATE, DATETIME or TIMESTAMP
created_at >= '2015-12-01' AND created_at < '2016-01-01'
_