1

次のシナリオを想像してください: 会社の従業員は、任意の質問 (整数値) に投票できます。

5 つの情報を取得する複雑な要求があります。

  1. 会社名
  2. 1社あたりの平均得票値
  3. 就業者数
  4. 投票数
  5. 参加(投票数/従業員数)

SQL クエリは、現在のユーザーが雇用されている企業の投票のみを取得します。

したがって、テーブル宣言の抜粋を見ると、4 つの異なるテーブルにアクセスしています。

User
- id

Company
- id
- name

Employment
- user_id (FK User.id)
- company_id (FK Company.id)

Vote
- company_name
- vote_value
- timestamp

Userおよび(n:m 関係ですが、追加のテーブルである必要があります)Companyによって関連付けられています。EmploymentテーブルVoteは PK/FK 関係では接続されませんが、会社名 ( ) によって会社に関連付けることができますCompany.name = Vote.company_name

次の SQL クエリによって、従業員数を除くすべての情報を正しく取得できました。

SELECT
    c.name AS company,
    AVG(v.vote_value) AS value,
    COUNT(e.user_id) AS employees,
    COUNT(f.face) AS votes,
    (COUNT(e.user_id) / COUNT(v.vote_value)) AS participation
FROM Company c
JOIN Employment e ON e.company_id = c.id
JOIN User u ON u.id = e.user_id
JOIN Vote v
    ON v.company_name = c.name
    AND YEAR(v.timestamp) = :year
    AND MONTH(v.timestamp) = :month
    AND DAY(v.timestamp) = :day
WHERE u.id = :u_id
GROUP BY v.company_name, e.company_id

ただし、正しい従業員数を取得する代わりに、employeeフィールドは常に投票数と等しくなります。(したがって、participation値も間違っています。)

サブクエリなしで1つのクエリでこれを実行する方法はありますか? クエリが正しい従業員数を取得するには、何を変更する必要がありますか?

1私は Doctrine2 を使用していますが、Doctrine がサブクエリをサポートしていないため、サブクエリを回避しようとしています。これを Doctrine の議論に持ち込みたくなかっただけです。そのため、このトピックを SQL レベルに分解しました。

4

3 に答える 3

1

これを試してみてください。投票を 1 つのサブクエリとして計算し、従業員を別のサブクエリとして計算します。

SELECT c.name,
ce.employee_count,
cv.vote_count,
cv.vote_count / ce.employee_count,
cv.vote_value
FROM 
(select company, count(*) AS 'employee_count' 
FROM employment GROUP BY company) ce
INNER JOIN company c
ON c.id = ce.company
INNER  JOIN 
(select company, AVG(vote_value) AS 'vote_value', count(*) as 'vote_count'
FROM vote v GROUP BY company) cv
ON c.id = cv.company
于 2013-10-02T21:55:20.397 に答える
1

従業員数を取得する場合、問題は、1 人の従業員のみでフィルタリングしていることです。

WHERE u.id = :u_id

第 2 に、従業員の数を数えたい場合で、投票のグループ化レベルに達している場合は、もちろん行の数が投票の数と同じになることに注意してください。したがって、@Przem ... として個別にカウントする必要があります。

COUNT(DISTINCT e.user_id) AS employees,

そうすれば、会社の従業員を一意に数えることができます (従業員が持っているすべての投票に対して繰り返される従業員 ID を取り除きます)。

あなたがコメントで述べたように:

従業員数として 1 を返します

これは、多くの投票を持つ 1 人の従業員を強制する where 条件のためです。個別は、where句によってフィルター処理された一意の 1 人の従業員のみをカウントするため、1 人しか得られません。ただし、これは正しい結果です (フィルター条件に基づく)。

句にサブクエリを追加するselectと、正しい結果が得られますが、パフォーマンスが犠牲になります。

于 2013-10-02T22:01:30.803 に答える