0

下面给出的是一个工作查询。我想用直接联合查询替换所有子查询。请建议我一个解决方案。

SELECT
  id,
  startTime,
  endTime,
  drawingTime,
  result,
  wpAmount,
  lpAmount,
  prize,
  cntWinTickets,
  cntLoosTickets
FROM (SELECT
    i.id            AS id,
    i.start_time    AS startTime,
    i.end_time      AS endTime,
    i.drawing_time  AS drawingTime,
    i.result        AS result,
    SUM( t.amount ) AS wpAmount,
    SUM( t.prize )  AS prize,
    COUNT( t.id )   AS cntWinTickets
      FROM issues i
    LEFT JOIN orders o
      ON o.issue_id = i.id
    LEFT JOIN tickets t
      ON t.order_id = o.id
        AND t.has_prize = 1
      GROUP BY i.id) AS A
  INNER JOIN (SELECT
        i.id            AS lid,
        SUM( t.amount ) AS lpAmount,
        COUNT( t.id )   AS cntLoosTickets
          FROM issues i
        LEFT JOIN orders o
          ON o.issue_id = i.id
        LEFT JOIN tickets t
          ON (t.order_id = o.id
              AND (t.has_prize = 0
                OR t.has_prize IS NULL))
          GROUP BY i.id) AS B
    ON A.id = B.lid
4

3 回答 3

2

这是一个解决方案,在 SUM 运算符中有一个花哨的叉积。我认为最好不要这样做,但这很有趣!

SELECT i.id AS id,
       i.start_time AS startTime,
       i.end_time AS endTime,
       i.drawing_time AS drawingTime,
       i.result AS result,
       SUM( t.amount*COALESCE(t.has_prize,0) ) AS wpAmount,
       SUM( t.prize*COALESCE(t.has_prize,0) ) AS prize,
       COUNT( case when t.has_prize=1 then t.id end ) AS cntWinTickets,
       SUM( t.amount*(1-COALESCE(t.has_prize,0)) ) AS lpAmount,
       COUNT( case when COALESCE(t.has_prize,0)=0 then t.id end ) AS cntLoosTickets
FROM issues i
LEFT JOIN orders o ON o.issue_id = i.id
LEFT JOIN tickets t ON t.order_id = o.id AND t.has_prize in (null,0,1)
GROUP BY i.id
于 2013-04-26T09:27:09.460 回答
1

这是您如何组合它的方法

SELECT
  i.id           AS id,
  i.start_time   AS startTime,
  i.end_time     AS endTime,
  i.drawing_time AS drawingTime,
  i.result       AS result,
  SUM(IF t.has_prize = 1,t.amount,0) AS wpAmount,
  SUM(IF t.has_prize = 1,t.prize,0) AS prize,
  COUNT(IF t.has_prize = 1,t.id,0) AS cntWinTickets,
  SUM(IF t.has_prize = 0,t.amount,0) AS lpAmount,
  COUNT(IF t.has_prize = 0,1,0) AS cntLoosTickets
FROM issues i
  LEFT JOIN orders o ON o.issue_id = i.id
  LEFT JOIN tickets t ON t.order_id = o.id
GROUP BY i.id

IF t.has_prize = 1,t.amount,0这意味着 if t.has_prize = 1than take t.amountelse take 0。另一种是 Mark 使用过的 CASE。

于 2013-04-26T09:33:48.383 回答
1

尝试:

SELECT i.id AS id, 
       i.start_time AS startTime, 
       i.end_time AS endTime, 
       i.drawing_time AS drawingTime, 
       i.result, 
       SUM(case when t.has_prize=1 then t.amount end) AS wpAmount, 
       SUM(case when t.has_prize=1 then t.prize end) AS prize, 
       COUNT(case when t.has_prize=1 then t.id end) AS cntWinTickets,
       SUM(case when coalesce(t.has_prize,0)=0 then t.amount end) AS lpAmount, 
       COUNT(case when coalesce(t.has_prize,0)=0 then t.id end) AS cntLoosTickets
FROM issues i
LEFT JOIN orders o ON o.issue_id = i.id
LEFT JOIN tickets t ON t.order_id = o.id AND t.has_prize in (null,0,1)
GROUP BY i.id
于 2013-04-26T09:30:24.710 回答