0

MySQLクエリの完成に問題があります。テーブルのチケット、請求書の行、ユーザーを組み合わせたと想像してみてください。各チケットには1つ以上の請求書行があり、各ユーザーは1つ以上のチケットを持つことができます。

名前バッジの作成に使用できるクエリを作成しようとしています。このバッジについては、その人が登録した名前とアイテムを知る必要があります。

次のMySQLクエリを作成しました

SELECT u.firstName, u.lastName, il.invID, il.name, 
CASE 
  WHEN il.name = 'Conference Dinner' 
  THEN 'Diner'
END AS 'conference_dinner',

CASE 
  WHEN il.name = 'Regular Conference Fee' THEN 'Conference'
  WHEN il.name = 'Conference Fee for Phd. Students'  THEN 'Conference'
END AS 'conference',

CASE
  WHEN il.name = 'Pre-Conference Fee' THEN 'Pre-Conference'
END AS 'pre_conference',

FROM invoice_line il, events_tickets et, users u
WHERE il.invID = et.invID
AND et.userID = u.ID

クエリはほぼ問題ありませんが、3つの請求書行(= 3つのアイテム)がテーブルに3行あるユーザーに対しては、これらの3つの行を1つの行にマージしたいと思います。ユーザーIDのGroupByは1行になりますが、作成された列が1行にマージされない場合よりも、そのうちの1つだけが表示されます。

私はこれを行うために間違った方法を使用した可能性があります。ただし、次のようなテーブルになるはずです。

firstName | lastName | conference_diner | conference | pre_conference |
----------------------------------------------------------------------
John      | Doe      | Diner            | Conference |                |
Jane      | Norman   |                  | Conference | Pre-Conference | 
Martijn   | Thomas   |                  | Conference |                |
Pete      | Johns    |                  |            | Pre-Conference |

現在、これは次の結果になります。

firstName | lastName | conference_diner | conference | pre_conference |
----------------------------------------------------------------------
John      | Doe      | Diner            |            |                |
John      | Doe      |                  | Conference |                |
Jane      | Norman   |                  | Conference |                |
Jane      | Norman   |                  |            | Pre-Conference |  
Martijn   | Thomas   |                  | Conference |                |
Pete      | Johns    |                  |            | Pre-Conference |

前もって感謝します

4

4 に答える 4

2

このようなもの:

SELECT u.firstName, u.lastName, et.invID,
CASE 
  WHEN il_d.name IS NULL THEN '' ELSE 'Diner'
END AS 'conference_dinner',

CASE 
  WHEN il_c.name IS NULL THEN '' ELSE 'Conference'
END AS 'conference',

CASE
  WHEN il_p.name IS NULL THEN '' ELSE 'Pre-Conference'
END AS 'pre_conference'
FROM events_tickets et
INNER JOIN users u ON et.userID = u.ID
LEFT JOIN invoice_line il_d ON il_d.invID = et.invID AND il_d.name = 'Conference Dinner'
LEFT JOIN invoice_line il_c ON il_c.invID = et.invID AND il_c.name IN ('Regular Conference Fee', 'Conference Fee for Phd. Students')
LEFT JOIN invoice_line il_p ON il_p.invID = et.invID AND il_p.name = 'Pre-Conference Fee'
于 2012-06-27T09:50:23.333 に答える
1

ソースデータを含めていないので、最終結果の各列が入力データの1つの行に関連していると仮定します。

これは、 ...を使用したいという意味です。GROUP BY

SELECT
  u.firstName, u.lastName, il.invID, il.name, 
  MAX(CASE
    WHEN il.name = 'Conference Dinner'                 THEN 'Diner'
  END) AS 'conference_dinner',
  MAX(CASE
    WHEN il.name = 'Regular Conference Fee'            THEN 'Conference'
    WHEN il.name = 'Conference Fee for Phd. Students'  THEN 'Conference'
  END) AS 'conference',    
  MAX(CASE
    WHEN il.name = 'Pre-Conference Fee'                THEN 'Pre-Conference'
  END) AS 'pre_conference'

FROM
  invoice_line il, events_tickets et, users u
WHERE
  il.invID = et.invID AND et.userID = u.ID
GROUP BY
  u.firstName, u.lastName

ただし、から削除する必要il.invID, il.name,がありましたSELECT。これは、それらが異なる値を持つ可能性があると推測しているためです。その場合、集計結果にどの値を表示しますか?

編集

これは、複数回ではなく、タルブを1回LEFT JOINだけスキャンするという点で、複数バージョンよりも優れています。invoice_lineこれ、読み取りが少なくなり、CPUが低くなる可能性があり、一般的に実行時間が短くなることを意味します。

il.invID欠点は、必要に応じてすべての個人とil.name値を抽出するのがわずかに複雑で、簡単ではないことです。

于 2012-06-27T09:51:49.083 に答える
1

あなたはこれらの線に沿って何かを試みるかもしれません:

SELECT u.firstName, u.lastName, il.invID, il.name,
IF(SUM(il.name = 'Conference Dinner') > 0,
    'Diner', '') AS 'conference_dinner',
IF(SUM(il.name IN ('Regular Conference Fee',
                   'Conference Fee for Phd. Students')) > 0,
    'Conference', '') AS 'conference',
IF(SUM(il.name = 'Pre-Conference Fee') > 0,
    'Pre-Conference', '') AS 'pre_conference'
FROM invoice_line il, events_tickets et, users u
WHERE il.invID = et.invID
AND et.userID = u.ID
GROUP BY u.ID

mysqlで比較すると、数値は0になり、falseの場合は0、 trueの場合は1になります。したがって、それらを単純に合計して、特定の式に一致する行を数えることができます。つまり、単一のユーザーに属する結合からのすべての行がグループ化され、特定のプロパティに一致する行がカウントされ、これらのカウントによって、結果のテーブルにそのユーザーの集計値として何を出力するかが決まります。

于 2012-06-27T09:53:11.543 に答える
0

event_ticketsテーブルにいくつかの自己結合を追加します

SELECT u.firstName, u.lastName, il.invID, il.name, 
CASE 
  WHEN il.name = 'Conference Dinner' 
  THEN 'Diner'
END AS 'conference_dinner',

CASE 
  WHEN il.name = 'Regular Conference Fee' THEN 'Conference'
  WHEN il.name = 'Conference Fee for Phd. Students'  THEN 'Conference'
END AS 'conference',

CASE
  WHEN il.name = 'Pre-Conference Fee' THEN 'Pre-Conference'
END AS 'pre_conference',

FROM invoice_line il, events_tickets et1, events_tickets et2, event_tickets et3, users u
WHERE il.invID = et.invID
AND et1.userID = u.ID
AND et2.userID = u.ID
AND et3.userID = u.ID

ただし、結合に何かを含めて、夕食を2回受け取らないようにします。たとえば、et.nameが「Diner」と「Conferece」などを指定する属性である場合は、次のようにする必要があります。

AND et1.name > et2.Name
AND et.name > et3.name

そしておそらくいくつかのヌル処理。

于 2012-06-27T09:58:00.190 に答える