2009-08-21 3 views
1

Ищу наводке о том, как оптимизировать это ....Использование присоединяется правильно

SELECT u.uid, 
     u.username, 
     u.nid, 
     wd.pay 
FROM  (users_data AS u 
      LEFT JOIN winners_data wd 
      ON u.nid = wd.nid 
       AND u.uid = wd.uid) 
     LEFT JOIN dp_node dn 
      ON u.nid = dn.nid 
WHERE u.uid = ".$val." 
     AND ((dn.TYPE = 'event' 
       AND (SELECT Count(nid) 
        FROM tournament_event 
        WHERE nid = u.nid 
          AND type_value IN ('A','B','C')) > 0) 
       OR (dn.TYPE = 'new_event' 
        AND (SELECT Count(nid) 
         FROM user_tournament_event 
         WHERE nid = u.nid 
           AND type_0_value IN ('Y','X')) > 0)) 
ORDER BY nid ASC 

На самом деле $ Вэл ничего, кроме UID, который приходит из следующего запроса по одному, как часть моей петли.

SELECT DISTINCT (dump.uid) FROM leader_Jdump AS свалка

Есть ли способ, чтобы добавить эту часть, а в приведенном выше запросе? Я думаю, это будет быстрее, если я смогу сделать это на уровне MySQL.

+0

Возможно, вы могли бы отложить запрос на удобочитаемость, я нахожу это трудно в мозге в этом формате. – Zoidberg

+3

AS u LEFT, мой мозг последовал за ним. –

+0

Я не уверен, что HTML поддерживается или отформатирован здесь. Итак, сообщение в livejournal. http://shantanuo.livejournal.com/64338.html – shantanuo

ответ

4

Попробуйте это:

SELECT u.uid, u.username, u.nid, wd.pay 
FROM users_data AS u 
LEFT JOIN 
     winners_data wd 
ON  (wd.nid, wd.uid) = (u.nid, u.uid) 
JOIN dp_node dn 
ON  dn.nid = u.nid 
     AND dn.type IN ('event', 'new_event') 
WHERE u.uid = ".$val." 
     AND EXISTS 
     (
     SELECT NULL 
     FROM tournament_event te 
     WHERE te.nid = u.nid 
       AND type_value IN ('A', 'B', 'C') 
       AND dn.type = 'event' 
     UNION ALL 
     SELECT NULL 
     FROM user_tournament_event te 
     WHERE te.nid = u.nid 
       AND type_0_value IN ('X', 'Y') 
       AND dn.type = 'new_event' 

     ) 
ORDER BY 
     u.nid ASC 

Я удалил OUTER JOIN из dp_node, так как исходный запрос требовал не- NULL условия на dp_node поле в WHERE пункте, так LEFT JOIN бесполезно здесь.

Создайте следующие показатели:

users_data (uid, nid) 
winners_data (uid, nid) 
dp_node (nid, event_type) 
tournament_event (nid, type_value) 
user_tournament_event (nid, type_0_value) 
+1

Черт тебя, Квасной, ты быстро. –

+1

'@ Leonel': Ты откладываешься, ты проигрываешь! – Quassnoi

+0

@ Lionel: Вы антропоморфны сценарий оболочки –

0

Это может быть эквивалентно, но проще читать:

WITH NIDs(type_value,nid) AS (
    SELECT 'event', nid FROM tournament_event 
    WHERE type_value IN ('A','B','C') 
    UNION ALL 
    SELECT 'new_event', nid FROM user_tournament_event 
    WHERE type_value IN ('X','Y') 
) 

SELECT 
    u.uid, 
    u.username, 
    u.nid, 
    wd.pay 
FROM users_data AS u JOIN NIDs AS n 
ON n.nid = u.nid 
AND n.type_value = u."type" 
LEFT JOIN winners_data AS wd 
ON u.nid=wd.nid AND u.uid=wd.uid 
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid 
WHERE u.uid=".$val." 
ORDER BY nid ASC 

Если «какое мероприятие» является важным, вы бы лучше с одной таблицей, из которой вы можете сделать это определение, посмотрев на один столбец или два. Кажется, у вас две таблицы, содержащие эту информацию (tournament_event и user_tournament_event). Например, вы можете хранить информацию как в выражении NID этого запроса.

Добавлено 2009-08-22:

Вот тот же запрос, с КТР выражается в виде производной таблицы:

SELECT 
    u.uid, 
    u.username, 
    u.nid, 
    wd.pay 
FROM users_data AS u JOIN (
    SELECT 'event', nid FROM tournament_event 
    WHERE type_value IN ('A','B','C') 
    UNION ALL 
    SELECT 'new_event', nid FROM user_tournament_event 
    WHERE type_value IN ('X','Y') 
) AS n(type_value,nid) 
ON n.nid = u.nid 
AND n.type_value = u."type" 
LEFT JOIN winners_data AS wd 
ON u.nid=wd.nid AND u.uid=wd.uid 
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid 
WHERE u.uid=".$val." 
ORDER BY nid ASC 
+1

FWIW, MySQL не поддерживает CTE. –

+0

@Bill: поддержка CTE не является проблемой, поскольку CTE можно переписать в виде производной таблицы. Я добавлю, что переписываю свой ответ, но я оставлю CTE, что может быть проще для людей читать. И в какой-то момент MySQL, вероятно, поддержит его, поскольку он некоторое время был частью стандарта ANSI/ISO. –

0

Я видел этот стиль (все закрытия скобки в конце одной строки) и интересно, как люди могут это понять. Кто-то спросил ранее для переформатированной версии:

SELECT u.uid, 
      u.username, 
      u.nid, 
      wd.pay 
FROM  users_data u 
      LEFT JOIN winners_data wd 
       ON u.nid = wd.nid 
       AND u.uid = wd.uid 
      LEFT JOIN dp_node dn 
       ON u.nid = dn.nid 
WHERE  u.uid = ".$val." 
      AND (
       (
        dn.TYPE = 'event' 
        AND (
         SELECT Count(nid) 
         FROM tournament_event 
         WHERE nid = u.nid 
           AND type_value IN ('A','B','C') 
        ) > 0 
       ) 
       OR (
        dn.TYPE = 'new_event' 
        AND (
         SELECT Count(nid) 
         FROM user_tournament_event 
         WHERE nid = u.nid 
           AND type_0_value IN ('Y','X') 
        ) > 0 
       ) 
     ) 
ORDER BY nid ASC